<!DOCTYPE HTML>
<html lang="zh-CN">


<head>
    <meta charset="utf-8">
    <meta name="keywords" content="Add System Call for XV6 (Unix Version 6), python,machine learning,deep learning,html,css,c,c++,cpp,cmake,ros,linux,ubuntu">
    <meta name="description" content="This blog introduces system call function call of XV6 (Unix Version 6) and also teachs how to add a function call">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
    <meta name="renderer" content="webkit|ie-stand|ie-comp">
    <meta name="mobile-web-app-capable" content="yes">
    <meta name="format-detection" content="telephone=no">
    <meta name="apple-mobile-web-app-capable" content="yes">
    <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
    <meta name="referrer" content="no-referrer-when-downgrade">
    <!-- Global site tag (gtag.js) - Google Analytics -->


    <title>Add System Call for XV6 (Unix Version 6) | JackWang&#39;s Blog</title>
    <link rel="icon" type="image/png" href="/favicon.png">

    <link rel="stylesheet" type="text/css" href="/libs/awesome/css/all.min.css">
    <link rel="stylesheet" type="text/css" href="/libs/materialize/materialize.min.css">
    <link rel="stylesheet" type="text/css" href="/libs/aos/aos.css">
    <link rel="stylesheet" type="text/css" href="/libs/animate/animate.min.css">
    <link rel="stylesheet" type="text/css" href="/libs/lightGallery/css/lightgallery.min.css">
    <link rel="stylesheet" type="text/css" href="/css/matery.css">
    <link rel="stylesheet" type="text/css" href="/css/my.css">

    <script src="/libs/jquery/jquery-3.6.0.min.js"></script>

<meta name="generator" content="Hexo 5.4.2">
<style>.github-emoji { position: relative; display: inline-block; width: 1.2em; min-height: 1.2em; overflow: hidden; vertical-align: top; color: transparent; }  .github-emoji > span { position: relative; z-index: 10; }  .github-emoji img, .github-emoji .fancybox { margin: 0 !important; padding: 0 !important; border: none !important; outline: none !important; text-decoration: none !important; user-select: none !important; cursor: auto !important; }  .github-emoji img { height: 1.2em !important; width: 1.2em !important; position: absolute !important; left: 50% !important; top: 50% !important; transform: translate(-50%, -50%) !important; user-select: none !important; cursor: auto !important; } .github-emoji-fallback { color: inherit; } .github-emoji-fallback img { opacity: 0 !important; }</style>
<link rel="stylesheet" href="/css/prism-tomorrow.css" type="text/css">
<link rel="stylesheet" href="/css/prism-line-numbers.css" type="text/css"></head>



   <style>
    body{
       background-image: url(https://cdn.jsdelivr.net/gh/Tokisaki-Galaxy/res/site/medias/background.jpg);
       background-repeat:no-repeat;
       background-size: 100% 100%;
       background-attachment:fixed;
    }
</style>



<body>
    <header class="navbar-fixed">
    <nav id="headNav" class="bg-color nav-transparent">
        <div id="navContainer" class="nav-wrapper container">
            <div class="brand-logo">
                <a href="/" class="waves-effect waves-light">
                    
                    <img src="/medias/logo.png" class="logo-img" alt="LOGO">
                    
                    <span class="logo-span">JackWang&#39;s Blog</span>
                </a>
            </div>
            

<a href="#" data-target="mobile-nav" class="sidenav-trigger button-collapse"><i class="fas fa-bars"></i></a>
<ul class="right nav-menu">
  
  <li class="hide-on-med-and-down nav-item">
    
    <a href="/" class="waves-effect waves-light">
      
      <i class="fas fa-home" style="zoom: 0.6;"></i>
      
      <span>首页</span>
    </a>
    
  </li>
  
  <li class="hide-on-med-and-down nav-item">
    
    <a href="" class="waves-effect waves-light">

      
      <i class="fas fa-book-reader" style="zoom: 0.6;"></i>
      
      <span>博客</span>
      <i class="fas fa-chevron-down" aria-hidden="true" style="zoom: 0.6;"></i>
    </a>
    <ul class="sub-nav menus_item_child ">
      
      <li>
        <a href="/tags">
          
          <i class="fas fa-tags" style="margin-top: -20px; zoom: 0.6;"></i>
          
	  <span>按标签归类文章</span>
        </a>
      </li>
      
      <li>
        <a href="/categories">
          
          <i class="fas fa-bookmark" style="margin-top: -20px; zoom: 0.6;"></i>
          
	  <span>按目录归类文章</span>
        </a>
      </li>
      
      <li>
        <a href="/archives">
          
          <i class="fas fa-archive" style="margin-top: -20px; zoom: 0.6;"></i>
          
	  <span>按日期分类文章</span>
        </a>
      </li>
      
    </ul>
    
  </li>
  
  <li class="hide-on-med-and-down nav-item">
    
    <a href="/about" class="waves-effect waves-light">
      
      <i class="fas fa-user-circle" style="zoom: 0.6;"></i>
      
      <span>关于</span>
    </a>
    
  </li>
  
  <li>
    <a href="#searchModal" class="modal-trigger waves-effect waves-light">
      <i id="searchIcon" class="fas fa-search" title="搜索" style="zoom: 0.85;"></i>
    </a>
  </li>
</ul>



<div id="mobile-nav" class="side-nav sidenav">

    <div class="mobile-head bg-color">
        
        <img src="/medias/logo.png" class="logo-img circle responsive-img">
        
        <div class="logo-name">JackWang&#39;s Blog</div>
        <div class="logo-desc">
            
            JackWang的个人博客
            
        </div>
    </div>

    <ul class="menu-list mobile-menu-list">
        
        <li class="m-nav-item">
	  
		<a href="/" class="waves-effect waves-light">
			
			    <i class="fa-fw fas fa-home"></i>
			
			首页
		</a>
          
        </li>
        
        <li class="m-nav-item">
	  
		<a href="javascript:;">
			
				<i class="fa-fw fas fa-book-reader"></i>
			
			博客
			<span class="m-icon"><i class="fas fa-chevron-right"></i></span>
		</a>
            <ul  style="background:  ;" >
              
                <li>

                  <a href="/tags " style="margin-left:75px">
				  
				   <i class="fa fas fa-tags" style="position: absolute;left:50px" ></i>
			      
                              <span>按标签归类文章</    span>

                  </a>
                </li>
              
                <li>

                  <a href="/categories " style="margin-left:75px">
				  
				   <i class="fa fas fa-bookmark" style="position: absolute;left:50px" ></i>
			      
                              <span>按目录归类文章</    span>

                  </a>
                </li>
              
                <li>

                  <a href="/archives " style="margin-left:75px">
				  
				   <i class="fa fas fa-archive" style="position: absolute;left:50px" ></i>
			      
                              <span>按日期分类文章</    span>

                  </a>
                </li>
              
            </ul>
          
        </li>
        
        <li class="m-nav-item">
	  
		<a href="/about" class="waves-effect waves-light">
			
			    <i class="fa-fw fas fa-user-circle"></i>
			
			关于
		</a>
          
        </li>
        
        
    </ul>
</div>


        </div>

        
    </nav>

</header>

    
<script src="/libs/cryptojs/crypto-js.min.js"></script>
<script>
    (function() {
        let pwd = '';
        if (pwd && pwd.length > 0) {
            if (pwd !== CryptoJS.SHA256(prompt('抱歉，这篇文章并不想让所有人都看到，请输入授权密码观看')).toString(CryptoJS.enc.Hex)) {
                alert('密码错误，将返回主页！');
                location.href = '/';
            }
        }
    })();
</script>




<div class="bg-cover pd-header post-cover" style="background-image: url('https://jack-1307599355.cos.ap-shanghai.myqcloud.com/image-20220928233603685.png')">
    <div class="container" style="right: 0px;left: 0px;">
        <div class="row">
            <div class="col s12 m12 l12">
                <div class="brand">
                    <h1 class="description center-align post-title">Add System Call for XV6 (Unix Version 6)</h1>
                </div>
            </div>
        </div>
    </div>
</div>




<main class="post-container content">

    
    <link rel="stylesheet" href="/libs/tocbot/tocbot.css">
<style>
    #articleContent h1::before,
    #articleContent h2::before,
    #articleContent h3::before,
    #articleContent h4::before,
    #articleContent h5::before,
    #articleContent h6::before {
        display: block;
        content: " ";
        height: 100px;
        margin-top: -100px;
        visibility: hidden;
    }

    #articleContent :focus {
        outline: none;
    }

    .toc-fixed {
        position: fixed;
        top: 64px;
    }

    .toc-widget {
        width: 345px;
        padding-left: 20px;
    }

    .toc-widget .toc-title {
        padding: 35px 0 15px 17px;
        font-size: 1.5rem;
        font-weight: bold;
        line-height: 1.5rem;
    }

    .toc-widget ol {
        padding: 0;
        list-style: none;
    }

    #toc-content {
        padding-bottom: 30px;
        overflow: auto;
    }

    #toc-content ol {
        padding-left: 10px;
    }

    #toc-content ol li {
        padding-left: 10px;
    }

    #toc-content .toc-link:hover {
        color: #42b983;
        font-weight: 700;
        text-decoration: underline;
    }

    #toc-content .toc-link::before {
        background-color: transparent;
        max-height: 25px;

        position: absolute;
        right: 23.5vw;
        display: block;
    }

    #toc-content .is-active-link {
        color: #42b983;
    }

    #floating-toc-btn {
        position: fixed;
        right: 15px;
        bottom: 76px;
        padding-top: 15px;
        margin-bottom: 0;
        z-index: 998;
    }

    #floating-toc-btn .btn-floating {
        width: 48px;
        height: 48px;
    }

    #floating-toc-btn .btn-floating i {
        line-height: 48px;
        font-size: 1.4rem;
    }
</style>
<div class="row">
    <div id="main-content" class="col s12 m12 l9">
        <!-- 文章内容详情 -->
<div id="artDetail">
    <div class="card">
        <div class="card-content article-info">
            <div class="row tag-cate">
                <div class="col s7">
                    
                    <div class="article-tag">
                        
                            <a href="/tags/Operating-System/">
                                <span class="chip bg-color">Operating System</span>
                            </a>
                        
                            <a href="/tags/xv6/">
                                <span class="chip bg-color">xv6</span>
                            </a>
                        
                    </div>
                    
                </div>
                <div class="col s5 right-align">
                    
                    <div class="post-cate">
                        <i class="fas fa-bookmark fa-fw icon-category"></i>
                        
                            <a href="/categories/%E6%9D%82%E9%A1%B9/" class="post-category">
                                杂项
                            </a>
                        
                    </div>
                    
                </div>
            </div>

            <div class="post-info">
                
                <div class="post-date info-break-policy">
                    <i class="far fa-calendar-minus fa-fw"></i>发布日期:&nbsp;&nbsp;
                    2022-09-27
                </div>
                

                
                <div class="post-date info-break-policy">
                    <i class="far fa-calendar-check fa-fw"></i>更新日期:&nbsp;&nbsp;
                    2023-06-01
                </div>
                

                
                <div class="info-break-policy">
                    <i class="far fa-file-word fa-fw"></i>文章字数:&nbsp;&nbsp;
                    3.4k
                </div>
                

                
                <div class="info-break-policy">
                    <i class="far fa-clock fa-fw"></i>阅读时长:&nbsp;&nbsp;
                    20 分
                </div>
                

                
                    <div id="busuanzi_container_page_pv" class="info-break-policy">
                        <i class="far fa-eye fa-fw"></i>阅读次数:&nbsp;&nbsp;
                        <span id="busuanzi_value_page_pv"></span>
                    </div>
				
            </div>
        </div>
        <hr class="clearfix">

        

        

        <div class="card-content article-card-content">
            <div id="articleContent">
                <p><img src="https://jack-1307599355.cos.ap-shanghai.myqcloud.com/image-20220928233603685.png" alt="XV6 (Unix Version 6) System"></p>
<h1 id="Add-System-Call-for-XV6-Unix-Version-6"><a href="#Add-System-Call-for-XV6-Unix-Version-6" class="headerlink" title="Add System Call for XV6 (Unix Version 6)"></a>Add System Call for XV6 (Unix Version 6)</h1><p>This blog introduces system call function call of XV6 (Unix Version 6) and also teachs how to add a function call</p>
<h2 id="1-What-we-want-to-do"><a href="#1-What-we-want-to-do" class="headerlink" title="1. What we want to do"></a>1. What we want to do</h2><p>We need to add my own system call <code>trace(const char *pathname)</code> and the second is <code>getcount()</code></p>
<p>The function prototypes are</p>
<pre class="line-numbers language-c"><code class="language-c"><span class="token keyword">int</span> <span class="token function">trace</span><span class="token punctuation">(</span><span class="token keyword">const</span> <span class="token keyword">char</span> <span class="token operator">*</span>pathname<span class="token punctuation">)</span>
<span class="token keyword">int</span> <span class="token function">getcount</span><span class="token punctuation">(</span><span class="token keyword">void</span><span class="token punctuation">)</span>
<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span></span></code></pre>
<p>In the following blog, I will cover what is system call and then introduce how to add a system call.</p>
<h2 id="2-Understanding-the-Makefile"><a href="#2-Understanding-the-Makefile" class="headerlink" title="2. Understanding the Makefile"></a>2. Understanding the <code>Makefile</code></h2><p>To understand the <code>xv6</code> system, we need to understand the <code>Makefile</code> first.</p>
<h3 id="A-Debug-command-make-qemu-nox-gdb"><a href="#A-Debug-command-make-qemu-nox-gdb" class="headerlink" title="A. Debug command: make qemu-nox-gdb"></a>A. Debug command: <code>make qemu-nox-gdb</code></h3><p>The command used to debug the xv6 system is <code>make qemu-nox-gdb</code>, which means we make the target <code>qemu-nox-gdb</code>.</p>
<p>The target <code>qemu-nox-gdb</code> in Makefile is</p>
<pre class="line-numbers language-makefile"><code class="language-makefile"><span class="token symbol">qemu-nox-gdb</span><span class="token punctuation">:</span> fs.img xv6.img .gdbinit
    <span class="token operator">@</span>echo <span class="token string">"*** Now run 'gdb'."</span> 1>&amp;2
    <span class="token variable">$</span><span class="token punctuation">(</span>QEMU<span class="token punctuation">)</span> -nographic <span class="token variable">$</span><span class="token punctuation">(</span>QEMUOPTS<span class="token punctuation">)</span> -S <span class="token variable">$</span><span class="token punctuation">(</span>QEMUGDB<span class="token punctuation">)</span>
<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span></span></code></pre>
<p>which means before make target <code>qemu-nox-gdb</code>, we need to make target <code>fs.img</code>, <code>xv6.img</code> and <code>.gdbinit</code>.</p>
<p>And the definitions of macro <code>QEMU</code>, <code>QEMUOPTS</code> and <code>QEMUGDB</code> are</p>
<pre class="line-numbers language-makefile"><code class="language-makefile">QEMU <span class="token operator">=</span> <span class="token variable">$</span><span class="token punctuation">(</span><span class="token keyword">shell</span> if which qemu > /dev/null<span class="token punctuation">;</span> \
    then echo qemu<span class="token punctuation">;</span> exit<span class="token punctuation">;</span> \
    elif which qemu-system-i386 > /dev/null<span class="token punctuation">;</span> \
    then echo qemu-system-i386<span class="token punctuation">;</span> exit<span class="token punctuation">;</span> \
    elif which qemu-system-x86_64 > /dev/null<span class="token punctuation">;</span> \
    then echo qemu-system-x86_64<span class="token punctuation">;</span> exit<span class="token punctuation">;</span> \
    <span class="token keyword">else</span> \
    qemu<span class="token operator">=</span>/Applications/Q.app/Contents/MacOS/i386-softmmu.app/Contents/MacOS/i386-softmmu<span class="token punctuation">;</span> \
    if test -x <span class="token variable">$$qemu;</span> then echo <span class="token variable">$$qemu;</span> exit<span class="token punctuation">;</span> fi<span class="token punctuation">;</span> fi<span class="token punctuation">;</span> \
    echo <span class="token string">"***"</span> 1>&amp;2<span class="token punctuation">;</span> \
    echo <span class="token string">"*** Error: Couldn't find a working QEMU executable."</span> 1>&amp;2<span class="token punctuation">;</span> \
    echo <span class="token string">"*** Is the directory containing the qemu binary in your PATH"</span> 1>&amp;2<span class="token punctuation">;</span> \
    echo <span class="token string">"*** or have you tried setting the QEMU variable in Makefile?"</span> 1>&amp;2<span class="token punctuation">;</span> \
    echo <span class="token string">"***"</span> 1>&amp;2<span class="token punctuation">;</span> exit 1<span class="token punctuation">)</span>
<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<pre class="line-numbers language-makefile"><code class="language-makefile">QEMUOPTS <span class="token operator">=</span> -drive file<span class="token operator">=</span>fs.img,index<span class="token operator">=</span>1,media<span class="token operator">=</span>disk,format<span class="token operator">=</span>raw -drive file<span class="token operator">=</span>xv6.img,index<span class="token operator">=</span>0,media<span class="token operator">=</span>disk,format<span class="token operator">=</span>raw -smp <span class="token variable">$</span><span class="token punctuation">(</span>CPUS<span class="token punctuation">)</span> -m 512 <span class="token variable">$</span><span class="token punctuation">(</span>QEMUEXTRA<span class="token punctuation">)</span>
<span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre>
<pre class="line-numbers language-makefile"><code class="language-makefile">QEMUGDB <span class="token operator">=</span> <span class="token variable">$</span><span class="token punctuation">(</span><span class="token keyword">shell</span> if <span class="token variable">$</span><span class="token punctuation">(</span>QEMU<span class="token punctuation">)</span> -help <span class="token operator">|</span> grep -q <span class="token string">'^-gdb'</span><span class="token punctuation">;</span> \
    then echo <span class="token string">"-gdb tcp::$(GDBPORT)"</span><span class="token punctuation">;</span> \
    <span class="token keyword">else</span> echo <span class="token string">"-s -p $(GDBPORT)"</span><span class="token punctuation">;</span> fi<span class="token punctuation">)</span>
<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span></span></code></pre>
<p>So, macro <code>QEMU</code> finds available <code>qemu</code> command on the machine and <code>QEMUOPTS</code> are command line options of qemu and <code>QEMUGDB</code> starts debug <code>QEMU</code> with <code>gdb</code>.</p>
<p><strong>Note that in <code>QEMUOPTS</code>, <code>-drive</code> option defines two driver <code>fs.img</code> and <code>vx6.img</code> </strong>.</p>
<h3 id="B-xv6-img"><a href="#B-xv6-img" class="headerlink" title="B. xv6.img"></a>B. <code>xv6.img</code></h3><p>Backtracing, the target <code>qemu-nox-gdb</code> depends target <code>xv6.img</code>, so take a look at target <code>xv6.img</code></p>
<pre class="line-numbers language-makefile"><code class="language-makefile"><span class="token symbol">xv6.img</span><span class="token punctuation">:</span> bootblock kernel
    dd if<span class="token operator">=</span>/dev/zero of<span class="token operator">=</span>xv6.img count<span class="token operator">=</span>10000
    dd if<span class="token operator">=</span>bootblock of<span class="token operator">=</span>xv6.img conv<span class="token operator">=</span>notrunc
    dd if<span class="token operator">=</span>kernel of<span class="token operator">=</span>xv6.img seek<span class="token operator">=</span>1 conv<span class="token operator">=</span>notrunc
<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span></span></code></pre>
<p>The command of target <code>xv6.img</code> simply creates disk image <code>xv6.img</code> and then bitwise copy <code>bootblock</code> and <code>kernel</code> into disk image <code>xv6.img</code>.</p>
<h3 id="C-kernel"><a href="#C-kernel" class="headerlink" title="C. kernel"></a>C. <code>kernel</code></h3><p>Again, the target <code>xv6.img</code> depends target <code>kernel</code>, we need to take a look at it.</p>
<pre class="line-numbers language-makefile"><code class="language-makefile"><span class="token symbol">kernel</span><span class="token punctuation">:</span> <span class="token variable">$</span><span class="token punctuation">(</span>OBJS<span class="token punctuation">)</span> entry.o entryother initcode kernel.ld
    <span class="token variable">$</span><span class="token punctuation">(</span>LD<span class="token punctuation">)</span> <span class="token variable">$</span><span class="token punctuation">(</span>LDFLAGS<span class="token punctuation">)</span> -T kernel.ld -o kernel entry.o <span class="token variable">$</span><span class="token punctuation">(</span>OBJS<span class="token punctuation">)</span> -b binary initcode entryother
    <span class="token variable">$</span><span class="token punctuation">(</span>OBJDUMP<span class="token punctuation">)</span> -S kernel > kernel.asm
    <span class="token variable">$</span><span class="token punctuation">(</span>OBJDUMP<span class="token punctuation">)</span> -t kernel <span class="token operator">|</span> sed <span class="token string">'1,/SYMBOL TABLE/d; s/ .* / /; /^$$/d'</span> > kernel.sym
<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span></span></code></pre>
<p>Here, we can see that target <code>kernel</code> uses <code>ld</code> to link all objective file togeter and generate binary file <code>kernel</code> after <code>-o</code> option.</p>
<h3 id="D-fs-img"><a href="#D-fs-img" class="headerlink" title="D. fs.img"></a>D. <code>fs.img</code></h3><p>Target <code>qemu-nox-gdb</code> also depends on target <code>fs.xv6</code>. Here’s the definition of target <code>fs.vx6</code> and relevent macro</p>
<pre class="line-numbers language-makefile"><code class="language-makefile">UPROGS<span class="token operator">=</span>\
    _cat\
    _echo\
    _forktest\
    _grep\
    _init\
    _kill\
    _ln\
    _ls\
    _mkdir\
    _rm\
    _sh\
    _stressfs\
    _usertests\
    _wc\
    _zombie\

<span class="token symbol">fs.img</span><span class="token punctuation">:</span> mkfs README <span class="token variable">$</span><span class="token punctuation">(</span>UPROGS<span class="token punctuation">)</span>
    ./mkfs fs.img README <span class="token variable">$</span><span class="token punctuation">(</span>UPROGS<span class="token punctuation">)</span>
<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<p>Target <code>fs.img</code> write user program <code>UPORGS</code> into <code>fs.img</code>.</p>
<h3 id="Summary"><a href="#Summary" class="headerlink" title="Summary"></a>Summary</h3><p>In summary, what does the command <code>make qemu-nox-gdb</code> do are:</p>
<ol>
<li>compile the kernel and write the kernel into <code>xv6.img</code></li>
<li>compile user programs and write user programs into <code>fs.img</code></li>
<li>start <code>qemu</code> with disk <code>xv6.img</code> and <code>fs.img</code></li>
<li>start <code>qemu</code> with <code>gdb</code> debugging</li>
</ol>
<p>After we firgure out the <code>Makefile</code> of the <code>xv6</code> project, we are now getting into the <code>xv6</code> project.</p>
<h2 id="3-The-Path-of-System-Call"><a href="#3-The-Path-of-System-Call" class="headerlink" title="3. The Path of System Call"></a>3. The Path of System Call</h2><p>After looking the <code>Makefile</code> of <code>xv6</code> project, we know that the kernel and user program are mutually independent programs. They are conceptually equal, both of them have <code>main</code> functions.</p>
<p>For example, in <code>main.c</code>, the <code>main</code> function of the program looks like</p>
<pre class="line-numbers language-c"><code class="language-c"><span class="token comment" spellcheck="true">// Bootstrap processor starts running C code here.</span>
<span class="token comment" spellcheck="true">// Allocate a real stack and switch to it, first</span>
<span class="token comment" spellcheck="true">// doing some setup required for memory allocator to work.</span>

<span class="token keyword">int</span>
<span class="token function">main</span><span class="token punctuation">(</span><span class="token keyword">void</span><span class="token punctuation">)</span>
<span class="token punctuation">{</span>
  <span class="token function">kinit1</span><span class="token punctuation">(</span>end<span class="token punctuation">,</span> <span class="token function">P2V</span><span class="token punctuation">(</span><span class="token number">4</span><span class="token operator">*</span><span class="token number">1024</span><span class="token operator">*</span><span class="token number">1024</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment" spellcheck="true">// phys page allocator</span>
  <span class="token function">kvmalloc</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>      <span class="token comment" spellcheck="true">// kernel page table</span>
  <span class="token function">mpinit</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>        <span class="token comment" spellcheck="true">// detect other processors</span>
  <span class="token function">lapicinit</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>     <span class="token comment" spellcheck="true">// interrupt controller</span>
  <span class="token function">seginit</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>       <span class="token comment" spellcheck="true">// segment descriptors</span>
  <span class="token function">picinit</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>       <span class="token comment" spellcheck="true">// disable pic</span>
  <span class="token function">ioapicinit</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token comment" spellcheck="true">// another interrupt controller</span>
  <span class="token function">consoleinit</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>   <span class="token comment" spellcheck="true">// console hardware</span>
  <span class="token function">uartinit</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>      <span class="token comment" spellcheck="true">// serial port</span>
  <span class="token function">pinit</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>         <span class="token comment" spellcheck="true">// process table</span>
  <span class="token function">tvinit</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>        <span class="token comment" spellcheck="true">// trap vectors      // == 中断向量表</span>
  <span class="token function">binit</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>         <span class="token comment" spellcheck="true">// buffer cache</span>
  <span class="token function">fileinit</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>      <span class="token comment" spellcheck="true">// file table</span>
  <span class="token function">ideinit</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>       <span class="token comment" spellcheck="true">// disk </span>
  <span class="token function">startothers</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>   <span class="token comment" spellcheck="true">// start other processors</span>
  <span class="token function">kinit2</span><span class="token punctuation">(</span><span class="token function">P2V</span><span class="token punctuation">(</span><span class="token number">4</span><span class="token operator">*</span><span class="token number">1024</span><span class="token operator">*</span><span class="token number">1024</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token function">P2V</span><span class="token punctuation">(</span>PHYSTOP<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment" spellcheck="true">// must come after startothers()</span>
  <span class="token function">userinit</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>      <span class="token comment" spellcheck="true">// first user process        // == 开启第一个用户进程</span>
  <span class="token function">mpmain</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>        <span class="token comment" spellcheck="true">// finish this processor's setup</span>
<span class="token punctuation">}</span>
<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<p>and the <code>main</code> function of user program <code>ls</code> looks like</p>
<pre class="line-numbers language-c"><code class="language-c"><span class="token keyword">int</span>
<span class="token function">main</span><span class="token punctuation">(</span><span class="token keyword">int</span> argc<span class="token punctuation">,</span> <span class="token keyword">char</span> <span class="token operator">*</span>argv<span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">)</span>
<span class="token punctuation">{</span>
  <span class="token keyword">int</span> i<span class="token punctuation">;</span>

  <span class="token keyword">if</span><span class="token punctuation">(</span>argc <span class="token operator">&lt;</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">{</span>
    <span class="token function">ls</span><span class="token punctuation">(</span><span class="token string">"."</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token function">exit</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token punctuation">}</span>
  <span class="token keyword">for</span><span class="token punctuation">(</span>i<span class="token operator">=</span><span class="token number">1</span><span class="token punctuation">;</span> i<span class="token operator">&lt;</span>argc<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span>
    <span class="token function">ls</span><span class="token punctuation">(</span>argv<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token function">exit</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<p>So, the user program and kernel are two independent program. </p>
<p><strong>Then, how does system call work</strong>?</p>
<h3 id="A-User-Program’s-Developer’s-Perspective-of-System-Call"><a href="#A-User-Program’s-Developer’s-Perspective-of-System-Call" class="headerlink" title="A. User Program’s (Developer’s) Perspective of System Call"></a>A. User Program’s (Developer’s) Perspective of System Call</h3><p>To start, we first look from the user program’s perspectie of system call.</p>
<pre class="line-numbers language-c"><code class="language-c"><span class="token comment" spellcheck="true">// User program test_trace.c</span>

<span class="token macro property">#<span class="token directive keyword">include</span> <span class="token string">"types.h"</span></span>
<span class="token macro property">#<span class="token directive keyword">include</span> <span class="token string">"stat.h"</span></span>
<span class="token macro property">#<span class="token directive keyword">include</span> <span class="token string">"user.h"</span></span>
<span class="token macro property">#<span class="token directive keyword">include</span> <span class="token string">"fcntl.h"</span></span>


<span class="token keyword">int</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token keyword">int</span> argc<span class="token punctuation">,</span> <span class="token keyword">char</span> <span class="token operator">*</span>argv<span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">)</span>
<span class="token punctuation">{</span>
  <span class="token keyword">int</span> <span class="token constant">stdout</span> <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span>

  <span class="token function">printf</span><span class="token punctuation">(</span><span class="token constant">stdout</span><span class="token punctuation">,</span> <span class="token string">"Start my syscall testing...\n"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

  <span class="token function">trace</span><span class="token punctuation">(</span><span class="token string">"ls"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token function">trace</span><span class="token punctuation">(</span><span class="token string">"pwd"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token function">trace</span><span class="token punctuation">(</span><span class="token string">"test"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token function">trace</span><span class="token punctuation">(</span><span class="token string">"666"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>


  <span class="token function">printf</span><span class="token punctuation">(</span><span class="token constant">stdout</span><span class="token punctuation">,</span> <span class="token string">"ls count = %d\n"</span><span class="token punctuation">,</span> <span class="token function">getcount</span><span class="token punctuation">(</span><span class="token string">"ls"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token function">open</span><span class="token punctuation">(</span><span class="token string">"ls"</span><span class="token punctuation">,</span> O_RDONLY<span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token function">printf</span><span class="token punctuation">(</span><span class="token constant">stdout</span><span class="token punctuation">,</span> <span class="token string">"ls count = %d\n"</span><span class="token punctuation">,</span> <span class="token function">getcount</span><span class="token punctuation">(</span><span class="token string">"ls"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token function">open</span><span class="token punctuation">(</span><span class="token string">"ls"</span><span class="token punctuation">,</span> O_RDONLY<span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token function">printf</span><span class="token punctuation">(</span><span class="token constant">stdout</span><span class="token punctuation">,</span> <span class="token string">"ls count = %d\n"</span><span class="token punctuation">,</span> <span class="token function">getcount</span><span class="token punctuation">(</span><span class="token string">"ls"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token function">open</span><span class="token punctuation">(</span><span class="token string">"ls"</span><span class="token punctuation">,</span> O_RDONLY<span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token function">printf</span><span class="token punctuation">(</span><span class="token constant">stdout</span><span class="token punctuation">,</span> <span class="token string">"ls count = %d\n"</span><span class="token punctuation">,</span> <span class="token function">getcount</span><span class="token punctuation">(</span><span class="token string">"ls"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>


  <span class="token function">open</span><span class="token punctuation">(</span><span class="token string">"pwd"</span><span class="token punctuation">,</span> O_RDONLY<span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token function">printf</span><span class="token punctuation">(</span><span class="token constant">stdout</span><span class="token punctuation">,</span> <span class="token string">"pwd count = %d\n"</span><span class="token punctuation">,</span> <span class="token function">getcount</span><span class="token punctuation">(</span><span class="token string">"pwd"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

  <span class="token function">open</span><span class="token punctuation">(</span><span class="token string">"test"</span><span class="token punctuation">,</span> O_RDONLY<span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token function">printf</span><span class="token punctuation">(</span><span class="token constant">stdout</span><span class="token punctuation">,</span> <span class="token string">"test count = %d\n"</span><span class="token punctuation">,</span> <span class="token function">getcount</span><span class="token punctuation">(</span><span class="token string">"test"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

  <span class="token function">open</span><span class="token punctuation">(</span><span class="token string">"pwd"</span><span class="token punctuation">,</span> O_RDONLY<span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token function">printf</span><span class="token punctuation">(</span><span class="token constant">stdout</span><span class="token punctuation">,</span> <span class="token string">"pwd count = %d\n"</span><span class="token punctuation">,</span> <span class="token function">getcount</span><span class="token punctuation">(</span><span class="token string">"pwd"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

  <span class="token function">open</span><span class="token punctuation">(</span><span class="token string">"666"</span><span class="token punctuation">,</span> O_RDONLY<span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token function">printf</span><span class="token punctuation">(</span><span class="token constant">stdout</span><span class="token punctuation">,</span> <span class="token string">"666 count = %d\n"</span><span class="token punctuation">,</span> <span class="token function">getcount</span><span class="token punctuation">(</span><span class="token string">"666"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

  <span class="token function">printf</span><span class="token punctuation">(</span><span class="token constant">stdout</span><span class="token punctuation">,</span> <span class="token string">"test finished\n"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

  <span class="token function">exit</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token punctuation">}</span>
<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<p><code>trace</code> and <code>getcount</code> are two system call. So from the perspective of user program, system call are just like function calls.</p>
<p>By using these <strong>special function</strong>, the user program can leverage functionalities offered by the kernel.</p>
<h3 id="B-Kernel’s-Operating-System’s-Perspective-of-System-Call"><a href="#B-Kernel’s-Operating-System’s-Perspective-of-System-Call" class="headerlink" title="B. Kernel’s (Operating System’s) Perspective of System Call"></a>B. Kernel’s (Operating System’s) Perspective of System Call</h3><p>Let us take a look of what does system call looks like in the perspective of kernel.</p>
<p><code>kill</code> is a system call, and it’s defined in <code>proc.c</code>.</p>
<pre class="line-numbers language-c"><code class="language-c"><span class="token comment" spellcheck="true">// proc.c</span>

<span class="token comment" spellcheck="true">// Kill the process with the given pid.</span>
<span class="token comment" spellcheck="true">// Process won't exit until it returns</span>
<span class="token comment" spellcheck="true">// to user space (see trap in trap.c).</span>
<span class="token keyword">int</span>
<span class="token function">kill</span><span class="token punctuation">(</span><span class="token keyword">int</span> pid<span class="token punctuation">)</span>
<span class="token punctuation">{</span>
  <span class="token keyword">struct</span> proc <span class="token operator">*</span>p<span class="token punctuation">;</span>

  <span class="token function">acquire</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>ptable<span class="token punctuation">.</span>lock<span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token keyword">for</span><span class="token punctuation">(</span>p <span class="token operator">=</span> ptable<span class="token punctuation">.</span>proc<span class="token punctuation">;</span> p <span class="token operator">&lt;</span> <span class="token operator">&amp;</span>ptable<span class="token punctuation">.</span>proc<span class="token punctuation">[</span>NPROC<span class="token punctuation">]</span><span class="token punctuation">;</span> p<span class="token operator">++</span><span class="token punctuation">)</span><span class="token punctuation">{</span>
    <span class="token keyword">if</span><span class="token punctuation">(</span>p<span class="token operator">-></span>pid <span class="token operator">==</span> pid<span class="token punctuation">)</span><span class="token punctuation">{</span>
      p<span class="token operator">-></span>killed <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span>
      <span class="token comment" spellcheck="true">// Wake process from sleep if necessary.</span>
      <span class="token keyword">if</span><span class="token punctuation">(</span>p<span class="token operator">-></span>state <span class="token operator">==</span> SLEEPING<span class="token punctuation">)</span>
        p<span class="token operator">-></span>state <span class="token operator">=</span> RUNNABLE<span class="token punctuation">;</span>
      <span class="token function">release</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>ptable<span class="token punctuation">.</span>lock<span class="token punctuation">)</span><span class="token punctuation">;</span>
      <span class="token keyword">return</span> <span class="token number">0</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
  <span class="token punctuation">}</span>
  <span class="token function">release</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>ptable<span class="token punctuation">.</span>lock<span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token keyword">return</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<p><strong>So, from the perspective of kernel, system call are just normal functions defined in kernel.</strong></p>
<p><strong>But here’s the problem, user program and kernel are two program, they are mutually independent. Since they do not link together, how can one program calls functions defined in another program</strong>?</p>
<h3 id="C-From-User-Program-to-Kernel"><a href="#C-From-User-Program-to-Kernel" class="headerlink" title="C. From User Program to Kernel"></a>C. From User Program to Kernel</h3><p>To solve the problem listed above, we need to understand the path from user program to kernel.</p>
<h4 id="1-usys-S"><a href="#1-usys-S" class="headerlink" title="1) usys.S "></a>1) <span id="scn"><code>usys.S</code> </span></h4><p>The first step of system call is <code>usys.S</code>. It’s a <code>AT&amp;T</code> format assembly, where it defines a macro function <code>SYSCALL</code></p>
<pre class="line-numbers language-assembly"><code class="language-assembly">#include "syscall.h"
#include "traps.h"

#define SYSCALL(name) \
  .globl name; \
  name: \
    movl $SYS_ ## name, %eax; \
    int $T_SYSCALL; \
    ret

SYSCALL(fork)
SYSCALL(exit)
SYSCALL(wait)
SYSCALL(pipe)
SYSCALL(read)
SYSCALL(write)
SYSCALL(close)
SYSCALL(kill)
SYSCALL(exec)
SYSCALL(open)
SYSCALL(mknod)
SYSCALL(unlink)
SYSCALL(fstat)
SYSCALL(link)
SYSCALL(mkdir)
SYSCALL(chdir)
SYSCALL(dup)
SYSCALL(getpid)
SYSCALL(sbrk)
SYSCALL(sleep)
SYSCALL(uptime)
<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<p><code>##</code> is concate operator in assembly, so after passing <code>fork</code> as parameter of <code>SYSCALL</code>, the function looks like</p>
<pre class="line-numbers language-assembly"><code class="language-assembly">; SYSCALL(fork) will expand as

#define SYSCALL(fork) \
  .globl fork; \
  fork: \
    movl $SYS_fork, %eax; \
    int $T_SYSCALL; \
    ret
<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<p>Variable <code>SYS_fork</code> is defined in <span id="anchor"> <code>syscall.h</code> </span></p>
<pre class="line-numbers language-c"><code class="language-c"><span class="token comment" spellcheck="true">// syscall.h</span>

<span class="token comment" spellcheck="true">// System call numbers</span>
<span class="token macro property">#<span class="token directive keyword">define</span> SYS_fork    1</span>
<span class="token macro property">#<span class="token directive keyword">define</span> SYS_exit    2</span>
<span class="token macro property">#<span class="token directive keyword">define</span> SYS_wait    3</span>
<span class="token macro property">#<span class="token directive keyword">define</span> SYS_pipe    4</span>
<span class="token macro property">#<span class="token directive keyword">define</span> SYS_read    5</span>
<span class="token macro property">#<span class="token directive keyword">define</span> SYS_kill    6</span>
<span class="token macro property">#<span class="token directive keyword">define</span> SYS_exec    7</span>
<span class="token macro property">#<span class="token directive keyword">define</span> SYS_fstat   8</span>
<span class="token macro property">#<span class="token directive keyword">define</span> SYS_chdir   9</span>
<span class="token macro property">#<span class="token directive keyword">define</span> SYS_dup    10</span>
<span class="token macro property">#<span class="token directive keyword">define</span> SYS_getpid 11</span>
<span class="token macro property">#<span class="token directive keyword">define</span> SYS_sbrk   12</span>
<span class="token macro property">#<span class="token directive keyword">define</span> SYS_sleep  13</span>
<span class="token macro property">#<span class="token directive keyword">define</span> SYS_uptime 14</span>
<span class="token macro property">#<span class="token directive keyword">define</span> SYS_open   15</span>
<span class="token macro property">#<span class="token directive keyword">define</span> SYS_write  16</span>
<span class="token macro property">#<span class="token directive keyword">define</span> SYS_mknod  17</span>
<span class="token macro property">#<span class="token directive keyword">define</span> SYS_unlink 18</span>
<span class="token macro property">#<span class="token directive keyword">define</span> SYS_link   19</span>
<span class="token macro property">#<span class="token directive keyword">define</span> SYS_mkdir  20</span>
<span class="token macro property">#<span class="token directive keyword">define</span> SYS_close  21</span>
<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<p>Also, the value of variable <code>T_SYSCALL</code> is <code>64</code>, defined in <code>traps.h</code></p>
<pre class="line-numbers language-c"><code class="language-c"><span class="token comment" spellcheck="true">// These are arbitrarily chosen, but with care not to overlap</span>
<span class="token comment" spellcheck="true">// processor defined exceptions or interrupt vectors.</span>
<span class="token macro property">#<span class="token directive keyword">define</span> T_SYSCALL       64      </span><span class="token comment" spellcheck="true">// system call</span>
<span class="token macro property">#<span class="token directive keyword">define</span> T_DEFAULT      500      </span><span class="token comment" spellcheck="true">// catchall</span>
<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span></span></code></pre>
<p>In summary, the macro function <code>SYSCALL</code> defines a assembly function that store the system call number into <code>eax</code> register and then call #64 interrput.</p>
<p>And <code>usys.S</code> simply defines assembly functions for all system call.</p>
<h4 id="2-vector-S"><a href="#2-vector-S" class="headerlink" title="2) vector.S"></a>2) <code>vector.S</code></h4><p>The next stop system call is <code>vector.S</code>, #64 is defined here.</p>
<pre class="line-numbers language-assembly"><code class="language-assembly">.globl vector64
vector64:
  pushl $0
  pushl $64
  jmp alltraps
<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<p><code>vector.S</code> simply push immediate number <code>0</code> and <code>64</code> into stack and then jump to function <code>alltraps</code>.</p>
<h4 id="3-trapasm-S"><a href="#3-trapasm-S" class="headerlink" title="3) trapasm.S"></a>3) <code>trapasm.S</code></h4><p><code>alltraps</code> is also an assembly function that defined in <code>trapasm.S</code></p>
<pre class="line-numbers language-assembly"><code class="language-assembly">.globl alltraps
alltraps:
  # Build trap frame.
  pushl %ds
  pushl %es
  pushl %fs
  pushl %gs
  pushal

  # Set up data segments.
  movw $(SEG_KDATA<<3), %ax
  movw %ax, %ds
  movw %ax, %es

  # Call trap(tf), where tf=%esp
  pushl %esp
  call trap
  addl $4, %esp
<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<p>Before jump to function <code>trap</code>, function <code>alltraps.S</code> push register into stack and them call function <code>trap</code>.</p>
<h4 id="4-trap-c"><a href="#4-trap-c" class="headerlink" title="4) trap.c"></a>4) <code>trap.c</code></h4><p>Function <code>trap</code> is defined in <code>trap.c</code> and <code>trap</code> is a <code>C</code> function.</p>
<p>The source code of <code>trap</code> doesn’t matter, the only thing we need to know is that on line #9, it calls <code>syscall</code> function to deal different system call.</p>
<p>What matters is:</p>
<ol>
<li><code>trap</code> takes an argument <code>struct trapframe *tf</code>. Calling a function and passing argument is easy within <code>C</code>, we can call <code>trap</code> like <code>trap(mytf)</code> in <code>my_trap_call_test.c</code>. But how to pass argument when we call <code>C</code> functions in assembly codes like <code>trapasm.S</code>?</li>
</ol>
<pre class="line-numbers language-c"><code class="language-c"><span class="token comment" spellcheck="true">//PAGEBREAK: 41</span>
<span class="token keyword">void</span>
<span class="token function">trap</span><span class="token punctuation">(</span><span class="token keyword">struct</span> trapframe <span class="token operator">*</span>tf<span class="token punctuation">)</span>
<span class="token punctuation">{</span>
  <span class="token keyword">if</span><span class="token punctuation">(</span>tf<span class="token operator">-></span>trapno <span class="token operator">==</span> T_SYSCALL<span class="token punctuation">)</span><span class="token punctuation">{</span>
    <span class="token keyword">if</span><span class="token punctuation">(</span><span class="token function">myproc</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">-></span>killed<span class="token punctuation">)</span>
      <span class="token function">exit</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token function">myproc</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">-></span>tf <span class="token operator">=</span> tf<span class="token punctuation">;</span>
    <span class="token function">syscall</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">if</span><span class="token punctuation">(</span><span class="token function">myproc</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">-></span>killed<span class="token punctuation">)</span>
      <span class="token function">exit</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">return</span><span class="token punctuation">;</span>
  <span class="token punctuation">}</span>

  <span class="token keyword">switch</span><span class="token punctuation">(</span>tf<span class="token operator">-></span>trapno<span class="token punctuation">)</span><span class="token punctuation">{</span>
  <span class="token keyword">case</span> T_IRQ0 <span class="token operator">+</span> IRQ_TIMER<span class="token punctuation">:</span>
    <span class="token keyword">if</span><span class="token punctuation">(</span><span class="token function">cpuid</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">==</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">{</span>
      <span class="token function">acquire</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>tickslock<span class="token punctuation">)</span><span class="token punctuation">;</span>
      ticks<span class="token operator">++</span><span class="token punctuation">;</span>
      <span class="token function">wakeup</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>ticks<span class="token punctuation">)</span><span class="token punctuation">;</span>
      <span class="token function">release</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>tickslock<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
    <span class="token function">lapiceoi</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">break</span><span class="token punctuation">;</span>
  <span class="token keyword">case</span> T_IRQ0 <span class="token operator">+</span> IRQ_IDE<span class="token punctuation">:</span>
    <span class="token function">ideintr</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token function">lapiceoi</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">break</span><span class="token punctuation">;</span>
  <span class="token keyword">case</span> T_IRQ0 <span class="token operator">+</span> IRQ_IDE<span class="token operator">+</span><span class="token number">1</span><span class="token punctuation">:</span>
    <span class="token comment" spellcheck="true">// Bochs generates spurious IDE1 interrupts.</span>
    <span class="token keyword">break</span><span class="token punctuation">;</span>
  <span class="token keyword">case</span> T_IRQ0 <span class="token operator">+</span> IRQ_KBD<span class="token punctuation">:</span>
    <span class="token function">kbdintr</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token function">lapiceoi</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">break</span><span class="token punctuation">;</span>
  <span class="token keyword">case</span> T_IRQ0 <span class="token operator">+</span> IRQ_COM1<span class="token punctuation">:</span>
    <span class="token function">uartintr</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token function">lapiceoi</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">break</span><span class="token punctuation">;</span>
  <span class="token keyword">case</span> T_IRQ0 <span class="token operator">+</span> <span class="token number">7</span><span class="token punctuation">:</span>
  <span class="token keyword">case</span> T_IRQ0 <span class="token operator">+</span> IRQ_SPURIOUS<span class="token punctuation">:</span>
    <span class="token function">cprintf</span><span class="token punctuation">(</span><span class="token string">"cpu%d: spurious interrupt at %x:%x\n"</span><span class="token punctuation">,</span>
            <span class="token function">cpuid</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> tf<span class="token operator">-></span>cs<span class="token punctuation">,</span> tf<span class="token operator">-></span>eip<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token function">lapiceoi</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">break</span><span class="token punctuation">;</span>

  <span class="token comment" spellcheck="true">//PAGEBREAK: 13</span>
  <span class="token keyword">default</span><span class="token punctuation">:</span>
    <span class="token keyword">if</span><span class="token punctuation">(</span><span class="token function">myproc</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">==</span> <span class="token number">0</span> <span class="token operator">||</span> <span class="token punctuation">(</span>tf<span class="token operator">-></span>cs<span class="token operator">&amp;</span><span class="token number">3</span><span class="token punctuation">)</span> <span class="token operator">==</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">{</span>
      <span class="token comment" spellcheck="true">// In kernel, it must be our mistake.</span>
      <span class="token function">cprintf</span><span class="token punctuation">(</span><span class="token string">"unexpected trap %d from cpu %d eip %x (cr2=0x%x)\n"</span><span class="token punctuation">,</span>
              tf<span class="token operator">-></span>trapno<span class="token punctuation">,</span> <span class="token function">cpuid</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> tf<span class="token operator">-></span>eip<span class="token punctuation">,</span> <span class="token function">rcr2</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
      <span class="token function">panic</span><span class="token punctuation">(</span><span class="token string">"trap"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
    <span class="token comment" spellcheck="true">// In user space, assume process misbehaved.</span>
    <span class="token function">cprintf</span><span class="token punctuation">(</span><span class="token string">"pid %d %s: trap %d err %d on cpu %d "</span>
            <span class="token string">"eip 0x%x addr 0x%x--kill proc\n"</span><span class="token punctuation">,</span>
            <span class="token function">myproc</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">-></span>pid<span class="token punctuation">,</span> <span class="token function">myproc</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">-></span>name<span class="token punctuation">,</span> tf<span class="token operator">-></span>trapno<span class="token punctuation">,</span>
            tf<span class="token operator">-></span>err<span class="token punctuation">,</span> <span class="token function">cpuid</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> tf<span class="token operator">-></span>eip<span class="token punctuation">,</span> <span class="token function">rcr2</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token function">myproc</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">-></span>killed <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span>
  <span class="token punctuation">}</span>
<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<p>The answer to problem 1 is that <code>C</code> passes function argument via stack. When we call functions between <code>C</code>, it is the compiler who autmatically push the argument into stack and hide all details.</p>
<p>So, when we call <code>C</code> functions in assembly, we need to push the argument into stack by ourselves. That’s the reason why assembly function <code>alltraps</code> pushes register into stack. <strong>The order of push is exactly reverse to the definition of <code>trapframe</code></strong>:</p>
<pre class="line-numbers language-c"><code class="language-c"><span class="token comment" spellcheck="true">// definition of trapframe in x86.h</span>

<span class="token comment" spellcheck="true">//PAGEBREAK: 36</span>
<span class="token comment" spellcheck="true">// Layout of the trap frame built on the stack by the</span>
<span class="token comment" spellcheck="true">// hardware and by trapasm.S, and passed to trap().</span>
<span class="token keyword">struct</span> trapframe <span class="token punctuation">{</span>
  <span class="token comment" spellcheck="true">// registers as pushed by pusha</span>
  uint edi<span class="token punctuation">;</span>
  uint esi<span class="token punctuation">;</span>
  uint ebp<span class="token punctuation">;</span>
  uint oesp<span class="token punctuation">;</span>      <span class="token comment" spellcheck="true">// useless &amp; ignored</span>
  uint ebx<span class="token punctuation">;</span>
  uint edx<span class="token punctuation">;</span>
  uint ecx<span class="token punctuation">;</span>
  uint eax<span class="token punctuation">;</span>

  <span class="token comment" spellcheck="true">// rest of trap frame</span>
  ushort gs<span class="token punctuation">;</span>
  ushort padding1<span class="token punctuation">;</span>
  ushort fs<span class="token punctuation">;</span>
  ushort padding2<span class="token punctuation">;</span>
  ushort es<span class="token punctuation">;</span>
  ushort padding3<span class="token punctuation">;</span>
  ushort ds<span class="token punctuation">;</span>
  ushort padding4<span class="token punctuation">;</span>
  uint trapno<span class="token punctuation">;</span>

  <span class="token comment" spellcheck="true">// below here defined by x86 hardware</span>
  uint err<span class="token punctuation">;</span>
  uint eip<span class="token punctuation">;</span>
  ushort cs<span class="token punctuation">;</span>
  ushort padding5<span class="token punctuation">;</span>
  uint eflags<span class="token punctuation">;</span>

  <span class="token comment" spellcheck="true">// below here only when crossing rings, such as from user to kernel</span>
  uint esp<span class="token punctuation">;</span>
  ushort ss<span class="token punctuation">;</span>
  ushort padding6<span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>


<span class="token comment" spellcheck="true">// push in alltraps</span>
<span class="token punctuation">.</span>globl alltraps
alltraps<span class="token punctuation">:</span>
  <span class="token macro property"># Build trap frame.</span>
  pushl <span class="token operator">%</span>ds
  pushl <span class="token operator">%</span>es
  pushl <span class="token operator">%</span>fs
  pushl <span class="token operator">%</span>gs
  pushal

  <span class="token macro property"># Set up data segments.</span>
  movw $<span class="token punctuation">(</span>SEG_KDATA<span class="token operator">&lt;&lt;</span><span class="token number">3</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token operator">%</span>ax
  movw <span class="token operator">%</span>ax<span class="token punctuation">,</span> <span class="token operator">%</span>ds
  movw <span class="token operator">%</span>ax<span class="token punctuation">,</span> <span class="token operator">%</span>es

  <span class="token macro property"># Call trap(tf), where tf=%esp</span>
  pushl <span class="token operator">%</span>esp
  call trap
  addl $<span class="token number">4</span><span class="token punctuation">,</span> <span class="token operator">%</span>esp
<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<p>Nonetheless, the most important thing here in <code>trap.c</code> is that <strong>we are already executing kernel codes</strong>, which means:</p>
<ol>
<li>we are already in kernel mode</li>
<li>we jump from user program to kernel.</li>
</ol>
<p><code>So, in summary, the os uses three assembly functions to jump from User Program to Kernel</code>.</p>
<h3 id="D-Interior-Mechanism-of-Syscall"><a href="#D-Interior-Mechanism-of-Syscall" class="headerlink" title="D. Interior Mechanism of Syscall"></a>D. Interior Mechanism of Syscall</h3><p>Continue, the function <code>syscall</code> is defined in <span id="sc"><code>syscall.c</code></span>.</p>
<pre class="line-numbers language-c"><code class="language-c"><span class="token comment" spellcheck="true">// syscall.c</span>

<span class="token keyword">extern</span> <span class="token keyword">int</span> <span class="token function">sys_chdir</span><span class="token punctuation">(</span><span class="token keyword">void</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">extern</span> <span class="token keyword">int</span> <span class="token function">sys_close</span><span class="token punctuation">(</span><span class="token keyword">void</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">extern</span> <span class="token keyword">int</span> <span class="token function">sys_dup</span><span class="token punctuation">(</span><span class="token keyword">void</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">extern</span> <span class="token keyword">int</span> <span class="token function">sys_exec</span><span class="token punctuation">(</span><span class="token keyword">void</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">extern</span> <span class="token keyword">int</span> <span class="token function">sys_exit</span><span class="token punctuation">(</span><span class="token keyword">void</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">extern</span> <span class="token keyword">int</span> <span class="token function">sys_fork</span><span class="token punctuation">(</span><span class="token keyword">void</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">extern</span> <span class="token keyword">int</span> <span class="token function">sys_fstat</span><span class="token punctuation">(</span><span class="token keyword">void</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">extern</span> <span class="token keyword">int</span> <span class="token function">sys_getpid</span><span class="token punctuation">(</span><span class="token keyword">void</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">extern</span> <span class="token keyword">int</span> <span class="token function">sys_kill</span><span class="token punctuation">(</span><span class="token keyword">void</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">extern</span> <span class="token keyword">int</span> <span class="token function">sys_link</span><span class="token punctuation">(</span><span class="token keyword">void</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">extern</span> <span class="token keyword">int</span> <span class="token function">sys_mkdir</span><span class="token punctuation">(</span><span class="token keyword">void</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">extern</span> <span class="token keyword">int</span> <span class="token function">sys_mknod</span><span class="token punctuation">(</span><span class="token keyword">void</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">extern</span> <span class="token keyword">int</span> <span class="token function">sys_open</span><span class="token punctuation">(</span><span class="token keyword">void</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">extern</span> <span class="token keyword">int</span> <span class="token function">sys_pipe</span><span class="token punctuation">(</span><span class="token keyword">void</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">extern</span> <span class="token keyword">int</span> <span class="token function">sys_read</span><span class="token punctuation">(</span><span class="token keyword">void</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">extern</span> <span class="token keyword">int</span> <span class="token function">sys_sbrk</span><span class="token punctuation">(</span><span class="token keyword">void</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">extern</span> <span class="token keyword">int</span> <span class="token function">sys_sleep</span><span class="token punctuation">(</span><span class="token keyword">void</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">extern</span> <span class="token keyword">int</span> <span class="token function">sys_unlink</span><span class="token punctuation">(</span><span class="token keyword">void</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">extern</span> <span class="token keyword">int</span> <span class="token function">sys_wait</span><span class="token punctuation">(</span><span class="token keyword">void</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">extern</span> <span class="token keyword">int</span> <span class="token function">sys_write</span><span class="token punctuation">(</span><span class="token keyword">void</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">extern</span> <span class="token keyword">int</span> <span class="token function">sys_uptime</span><span class="token punctuation">(</span><span class="token keyword">void</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token keyword">static</span> <span class="token keyword">int</span> <span class="token punctuation">(</span><span class="token operator">*</span>syscalls<span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">(</span><span class="token keyword">void</span><span class="token punctuation">)</span> <span class="token operator">=</span> <span class="token punctuation">{</span>
<span class="token punctuation">[</span>SYS_fork<span class="token punctuation">]</span>    sys_fork<span class="token punctuation">,</span>
<span class="token punctuation">[</span>SYS_exit<span class="token punctuation">]</span>    sys_exit<span class="token punctuation">,</span>
<span class="token punctuation">[</span>SYS_wait<span class="token punctuation">]</span>    sys_wait<span class="token punctuation">,</span>
<span class="token punctuation">[</span>SYS_pipe<span class="token punctuation">]</span>    sys_pipe<span class="token punctuation">,</span>
<span class="token punctuation">[</span>SYS_read<span class="token punctuation">]</span>    sys_read<span class="token punctuation">,</span>
<span class="token punctuation">[</span>SYS_kill<span class="token punctuation">]</span>    sys_kill<span class="token punctuation">,</span>
<span class="token punctuation">[</span>SYS_exec<span class="token punctuation">]</span>    sys_exec<span class="token punctuation">,</span>
<span class="token punctuation">[</span>SYS_fstat<span class="token punctuation">]</span>   sys_fstat<span class="token punctuation">,</span>
<span class="token punctuation">[</span>SYS_chdir<span class="token punctuation">]</span>   sys_chdir<span class="token punctuation">,</span>
<span class="token punctuation">[</span>SYS_dup<span class="token punctuation">]</span>     sys_dup<span class="token punctuation">,</span>
<span class="token punctuation">[</span>SYS_getpid<span class="token punctuation">]</span>  sys_getpid<span class="token punctuation">,</span>
<span class="token punctuation">[</span>SYS_sbrk<span class="token punctuation">]</span>    sys_sbrk<span class="token punctuation">,</span>
<span class="token punctuation">[</span>SYS_sleep<span class="token punctuation">]</span>   sys_sleep<span class="token punctuation">,</span>
<span class="token punctuation">[</span>SYS_uptime<span class="token punctuation">]</span>  sys_uptime<span class="token punctuation">,</span>
<span class="token punctuation">[</span>SYS_open<span class="token punctuation">]</span>    sys_open<span class="token punctuation">,</span>
<span class="token punctuation">[</span>SYS_write<span class="token punctuation">]</span>   sys_write<span class="token punctuation">,</span>
<span class="token punctuation">[</span>SYS_mknod<span class="token punctuation">]</span>   sys_mknod<span class="token punctuation">,</span>
<span class="token punctuation">[</span>SYS_unlink<span class="token punctuation">]</span>  sys_unlink<span class="token punctuation">,</span>
<span class="token punctuation">[</span>SYS_link<span class="token punctuation">]</span>    sys_link<span class="token punctuation">,</span>
<span class="token punctuation">[</span>SYS_mkdir<span class="token punctuation">]</span>   sys_mkdir<span class="token punctuation">,</span>
<span class="token punctuation">[</span>SYS_close<span class="token punctuation">]</span>   sys_close<span class="token punctuation">,</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>

<span class="token keyword">void</span>
<span class="token function">syscall</span><span class="token punctuation">(</span><span class="token keyword">void</span><span class="token punctuation">)</span>
<span class="token punctuation">{</span>
  <span class="token keyword">int</span> num<span class="token punctuation">;</span>
  <span class="token keyword">struct</span> proc <span class="token operator">*</span>curproc <span class="token operator">=</span> <span class="token function">myproc</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

  num <span class="token operator">=</span> curproc<span class="token operator">-></span>tf<span class="token operator">-></span>eax<span class="token punctuation">;</span>
  <span class="token keyword">if</span><span class="token punctuation">(</span>num <span class="token operator">></span> <span class="token number">0</span> <span class="token operator">&amp;&amp;</span> num <span class="token operator">&lt;</span> <span class="token function">NELEM</span><span class="token punctuation">(</span>syscalls<span class="token punctuation">)</span> <span class="token operator">&amp;&amp;</span> syscalls<span class="token punctuation">[</span>num<span class="token punctuation">]</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    curproc<span class="token operator">-></span>tf<span class="token operator">-></span>eax <span class="token operator">=</span> syscalls<span class="token punctuation">[</span>num<span class="token punctuation">]</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span>
    <span class="token function">cprintf</span><span class="token punctuation">(</span><span class="token string">"%d %s: unknown sys call %d\n"</span><span class="token punctuation">,</span>
            curproc<span class="token operator">-></span>pid<span class="token punctuation">,</span> curproc<span class="token operator">-></span>name<span class="token punctuation">,</span> num<span class="token punctuation">)</span><span class="token punctuation">;</span>
    curproc<span class="token operator">-></span>tf<span class="token operator">-></span>eax <span class="token operator">=</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">;</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<p>Variable <code>syscall</code> is a function array, and <code>SYS_xxx</code> are macros defined in <code>syscall.h</code> (refer <a href="#anchor">syscall.h</a>)</p>
<p>Rember, system call number is store in <code>eax</code> (refer <a href="#scn">usys.S</a>).</p>
<p>So, <code>syscall</code> first get the system call number from <code>eax</code> register (line #55), and then pick out corresponding system call function to run (line #57).</p>
<p> <code>extern</code> is used to mark up system call function like <code>sys_exit</code>, <code>sys_close</code>, and <code>sys_mkdir</code> are defined in other files, </p>
<p>Finally, take a look at the real definition of <code>sys_kill</code> in <code>sysproc.c</code></p>
<pre class="line-numbers language-c"><code class="language-c"><span class="token comment" spellcheck="true">// sysproc.c</span>
<span class="token keyword">int</span>
<span class="token function">sys_kill</span><span class="token punctuation">(</span><span class="token keyword">void</span><span class="token punctuation">)</span>
<span class="token punctuation">{</span>
  <span class="token keyword">int</span> pid<span class="token punctuation">;</span>

  <span class="token keyword">if</span><span class="token punctuation">(</span><span class="token function">argint</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">,</span> <span class="token operator">&amp;</span>pid<span class="token punctuation">)</span> <span class="token operator">&lt;</span> <span class="token number">0</span><span class="token punctuation">)</span>
    <span class="token keyword">return</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">;</span>
  <span class="token keyword">return</span> <span class="token function">kill</span><span class="token punctuation">(</span>pid<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<p>and <code>kill</code> in <code>proc.c</code></p>
<pre class="line-numbers language-c"><code class="language-c"><span class="token comment" spellcheck="true">// proc.c</span>

<span class="token comment" spellcheck="true">// Kill the process with the given pid.</span>
<span class="token comment" spellcheck="true">// Process won't exit until it returns</span>
<span class="token comment" spellcheck="true">// to user space (see trap in trap.c).</span>
<span class="token keyword">int</span>
<span class="token function">kill</span><span class="token punctuation">(</span><span class="token keyword">int</span> pid<span class="token punctuation">)</span>
<span class="token punctuation">{</span>
  <span class="token keyword">struct</span> proc <span class="token operator">*</span>p<span class="token punctuation">;</span>

  <span class="token function">acquire</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>ptable<span class="token punctuation">.</span>lock<span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token keyword">for</span><span class="token punctuation">(</span>p <span class="token operator">=</span> ptable<span class="token punctuation">.</span>proc<span class="token punctuation">;</span> p <span class="token operator">&lt;</span> <span class="token operator">&amp;</span>ptable<span class="token punctuation">.</span>proc<span class="token punctuation">[</span>NPROC<span class="token punctuation">]</span><span class="token punctuation">;</span> p<span class="token operator">++</span><span class="token punctuation">)</span><span class="token punctuation">{</span>
    <span class="token keyword">if</span><span class="token punctuation">(</span>p<span class="token operator">-></span>pid <span class="token operator">==</span> pid<span class="token punctuation">)</span><span class="token punctuation">{</span>
      p<span class="token operator">-></span>killed <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span>
      <span class="token comment" spellcheck="true">// Wake process from sleep if necessary.</span>
      <span class="token keyword">if</span><span class="token punctuation">(</span>p<span class="token operator">-></span>state <span class="token operator">==</span> SLEEPING<span class="token punctuation">)</span>
        p<span class="token operator">-></span>state <span class="token operator">=</span> RUNNABLE<span class="token punctuation">;</span>
      <span class="token function">release</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>ptable<span class="token punctuation">.</span>lock<span class="token punctuation">)</span><span class="token punctuation">;</span>
      <span class="token keyword">return</span> <span class="token number">0</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
  <span class="token punctuation">}</span>
  <span class="token function">release</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>ptable<span class="token punctuation">.</span>lock<span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token keyword">return</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<h3 id="F-One-More-Thing-Passing-Argument"><a href="#F-One-More-Thing-Passing-Argument" class="headerlink" title="F. One More Thing: Passing Argument"></a>F. One More Thing: Passing Argument</h3><p>User program can include <code>user.h</code>, where prototypes of system call are provided.</p>
<pre class="line-numbers language-c"><code class="language-c"><span class="token comment" spellcheck="true">// user.h</span>

<span class="token comment" spellcheck="true">// system calls</span>
<span class="token keyword">int</span> <span class="token function">fork</span><span class="token punctuation">(</span><span class="token keyword">void</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">int</span> <span class="token function">exit</span><span class="token punctuation">(</span><span class="token keyword">void</span><span class="token punctuation">)</span> <span class="token function">__attribute__</span><span class="token punctuation">(</span><span class="token punctuation">(</span>noreturn<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">int</span> <span class="token function">wait</span><span class="token punctuation">(</span><span class="token keyword">void</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">int</span> <span class="token function">pipe</span><span class="token punctuation">(</span><span class="token keyword">int</span><span class="token operator">*</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">int</span> <span class="token function">write</span><span class="token punctuation">(</span><span class="token keyword">int</span><span class="token punctuation">,</span> <span class="token keyword">const</span> <span class="token keyword">void</span><span class="token operator">*</span><span class="token punctuation">,</span> <span class="token keyword">int</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">int</span> <span class="token function">read</span><span class="token punctuation">(</span><span class="token keyword">int</span><span class="token punctuation">,</span> <span class="token keyword">void</span><span class="token operator">*</span><span class="token punctuation">,</span> <span class="token keyword">int</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">int</span> <span class="token function">close</span><span class="token punctuation">(</span><span class="token keyword">int</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">int</span> <span class="token function">kill</span><span class="token punctuation">(</span><span class="token keyword">int</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">int</span> <span class="token function">exec</span><span class="token punctuation">(</span><span class="token keyword">char</span><span class="token operator">*</span><span class="token punctuation">,</span> <span class="token keyword">char</span><span class="token operator">*</span><span class="token operator">*</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">int</span> <span class="token function">open</span><span class="token punctuation">(</span><span class="token keyword">const</span> <span class="token keyword">char</span><span class="token operator">*</span><span class="token punctuation">,</span> <span class="token keyword">int</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">int</span> <span class="token function">mknod</span><span class="token punctuation">(</span><span class="token keyword">const</span> <span class="token keyword">char</span><span class="token operator">*</span><span class="token punctuation">,</span> <span class="token keyword">short</span><span class="token punctuation">,</span> <span class="token keyword">short</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">int</span> <span class="token function">unlink</span><span class="token punctuation">(</span><span class="token keyword">const</span> <span class="token keyword">char</span><span class="token operator">*</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">int</span> <span class="token function">fstat</span><span class="token punctuation">(</span><span class="token keyword">int</span> fd<span class="token punctuation">,</span> <span class="token keyword">struct</span> stat<span class="token operator">*</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">int</span> <span class="token function">link</span><span class="token punctuation">(</span><span class="token keyword">const</span> <span class="token keyword">char</span><span class="token operator">*</span><span class="token punctuation">,</span> <span class="token keyword">const</span> <span class="token keyword">char</span><span class="token operator">*</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">int</span> <span class="token function">mkdir</span><span class="token punctuation">(</span><span class="token keyword">const</span> <span class="token keyword">char</span><span class="token operator">*</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">int</span> <span class="token function">chdir</span><span class="token punctuation">(</span><span class="token keyword">const</span> <span class="token keyword">char</span><span class="token operator">*</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">int</span> <span class="token function">dup</span><span class="token punctuation">(</span><span class="token keyword">int</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">int</span> <span class="token function">getpid</span><span class="token punctuation">(</span><span class="token keyword">void</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">char</span><span class="token operator">*</span> <span class="token function">sbrk</span><span class="token punctuation">(</span><span class="token keyword">int</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">int</span> <span class="token function">sleep</span><span class="token punctuation">(</span><span class="token keyword">int</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">int</span> <span class="token function">uptime</span><span class="token punctuation">(</span><span class="token keyword">void</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<p>However, the function prototype defined in <code>syscall.c</code> has not argument (refer <a href="#sc">syscall.c</a>).</p>
<pre class="line-numbers language-c"><code class="language-c"><span class="token keyword">extern</span> <span class="token keyword">int</span> <span class="token function">sys_chdir</span><span class="token punctuation">(</span><span class="token keyword">void</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">extern</span> <span class="token keyword">int</span> <span class="token function">sys_close</span><span class="token punctuation">(</span><span class="token keyword">void</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">extern</span> <span class="token keyword">int</span> <span class="token function">sys_dup</span><span class="token punctuation">(</span><span class="token keyword">void</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">extern</span> <span class="token keyword">int</span> <span class="token function">sys_exec</span><span class="token punctuation">(</span><span class="token keyword">void</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">extern</span> <span class="token keyword">int</span> <span class="token function">sys_exit</span><span class="token punctuation">(</span><span class="token keyword">void</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">extern</span> <span class="token keyword">int</span> <span class="token function">sys_fork</span><span class="token punctuation">(</span><span class="token keyword">void</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">extern</span> <span class="token keyword">int</span> <span class="token function">sys_fstat</span><span class="token punctuation">(</span><span class="token keyword">void</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">extern</span> <span class="token keyword">int</span> <span class="token function">sys_getpid</span><span class="token punctuation">(</span><span class="token keyword">void</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">extern</span> <span class="token keyword">int</span> <span class="token function">sys_kill</span><span class="token punctuation">(</span><span class="token keyword">void</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">extern</span> <span class="token keyword">int</span> <span class="token function">sys_link</span><span class="token punctuation">(</span><span class="token keyword">void</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">extern</span> <span class="token keyword">int</span> <span class="token function">sys_mkdir</span><span class="token punctuation">(</span><span class="token keyword">void</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">extern</span> <span class="token keyword">int</span> <span class="token function">sys_mknod</span><span class="token punctuation">(</span><span class="token keyword">void</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">extern</span> <span class="token keyword">int</span> <span class="token function">sys_open</span><span class="token punctuation">(</span><span class="token keyword">void</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">extern</span> <span class="token keyword">int</span> <span class="token function">sys_pipe</span><span class="token punctuation">(</span><span class="token keyword">void</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">extern</span> <span class="token keyword">int</span> <span class="token function">sys_read</span><span class="token punctuation">(</span><span class="token keyword">void</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">extern</span> <span class="token keyword">int</span> <span class="token function">sys_sbrk</span><span class="token punctuation">(</span><span class="token keyword">void</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">extern</span> <span class="token keyword">int</span> <span class="token function">sys_sleep</span><span class="token punctuation">(</span><span class="token keyword">void</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">extern</span> <span class="token keyword">int</span> <span class="token function">sys_unlink</span><span class="token punctuation">(</span><span class="token keyword">void</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">extern</span> <span class="token keyword">int</span> <span class="token function">sys_wait</span><span class="token punctuation">(</span><span class="token keyword">void</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">extern</span> <span class="token keyword">int</span> <span class="token function">sys_write</span><span class="token punctuation">(</span><span class="token keyword">void</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">extern</span> <span class="token keyword">int</span> <span class="token function">sys_uptime</span><span class="token punctuation">(</span><span class="token keyword">void</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<p>As explained ahead, <code>C</code> uses stack to pass the argument when calling function. So, <strong>we can actually get argument via calling program’s stack</strong>.</p>
<p>Here, we remain the pototype argument void is because the function array <code>syscall</code> that forces us keeping the prototype same argument.</p>
<p>To get the argument from calling program’s stack, we can use function <code>argstr</code> and <code>argint</code> defined in <code>syscall.c</code></p>
<pre class="line-numbers language-c"><code class="language-c"><span class="token comment" spellcheck="true">// Fetch the int at addr from the current process.</span>
<span class="token keyword">int</span>
<span class="token function">fetchint</span><span class="token punctuation">(</span>uint addr<span class="token punctuation">,</span> <span class="token keyword">int</span> <span class="token operator">*</span>ip<span class="token punctuation">)</span>
<span class="token punctuation">{</span>
  <span class="token keyword">struct</span> proc <span class="token operator">*</span>curproc <span class="token operator">=</span> <span class="token function">myproc</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

  <span class="token keyword">if</span><span class="token punctuation">(</span>addr <span class="token operator">>=</span> curproc<span class="token operator">-></span>sz <span class="token operator">||</span> addr<span class="token operator">+</span><span class="token number">4</span> <span class="token operator">></span> curproc<span class="token operator">-></span>sz<span class="token punctuation">)</span>
    <span class="token keyword">return</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">;</span>
  <span class="token operator">*</span>ip <span class="token operator">=</span> <span class="token operator">*</span><span class="token punctuation">(</span><span class="token keyword">int</span><span class="token operator">*</span><span class="token punctuation">)</span><span class="token punctuation">(</span>addr<span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token keyword">return</span> <span class="token number">0</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token comment" spellcheck="true">// Fetch the nul-terminated string at addr from the current process.</span>
<span class="token comment" spellcheck="true">// Doesn't actually copy the string - just sets *pp to point at it.</span>
<span class="token comment" spellcheck="true">// Returns length of string, not including nul.</span>
<span class="token keyword">int</span>
<span class="token function">fetchstr</span><span class="token punctuation">(</span>uint addr<span class="token punctuation">,</span> <span class="token keyword">char</span> <span class="token operator">*</span><span class="token operator">*</span>pp<span class="token punctuation">)</span>
<span class="token punctuation">{</span>
  <span class="token keyword">char</span> <span class="token operator">*</span>s<span class="token punctuation">,</span> <span class="token operator">*</span>ep<span class="token punctuation">;</span>
  <span class="token keyword">struct</span> proc <span class="token operator">*</span>curproc <span class="token operator">=</span> <span class="token function">myproc</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

  <span class="token keyword">if</span><span class="token punctuation">(</span>addr <span class="token operator">>=</span> curproc<span class="token operator">-></span>sz<span class="token punctuation">)</span>
    <span class="token keyword">return</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">;</span>
  <span class="token operator">*</span>pp <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token keyword">char</span><span class="token operator">*</span><span class="token punctuation">)</span>addr<span class="token punctuation">;</span>
  ep <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token keyword">char</span><span class="token operator">*</span><span class="token punctuation">)</span>curproc<span class="token operator">-></span>sz<span class="token punctuation">;</span>
  <span class="token keyword">for</span><span class="token punctuation">(</span>s <span class="token operator">=</span> <span class="token operator">*</span>pp<span class="token punctuation">;</span> s <span class="token operator">&lt;</span> ep<span class="token punctuation">;</span> s<span class="token operator">++</span><span class="token punctuation">)</span><span class="token punctuation">{</span>
    <span class="token keyword">if</span><span class="token punctuation">(</span><span class="token operator">*</span>s <span class="token operator">==</span> <span class="token number">0</span><span class="token punctuation">)</span>
      <span class="token keyword">return</span> s <span class="token operator">-</span> <span class="token operator">*</span>pp<span class="token punctuation">;</span>
  <span class="token punctuation">}</span>
  <span class="token keyword">return</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token comment" spellcheck="true">// Fetch the nth 32-bit system call argument.</span>
<span class="token keyword">int</span>
<span class="token function">argint</span><span class="token punctuation">(</span><span class="token keyword">int</span> n<span class="token punctuation">,</span> <span class="token keyword">int</span> <span class="token operator">*</span>ip<span class="token punctuation">)</span>
<span class="token punctuation">{</span>
  <span class="token keyword">return</span> <span class="token function">fetchint</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token function">myproc</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">-></span>tf<span class="token operator">-></span>esp<span class="token punctuation">)</span> <span class="token operator">+</span> <span class="token number">4</span> <span class="token operator">+</span> <span class="token number">4</span><span class="token operator">*</span>n<span class="token punctuation">,</span> ip<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token comment" spellcheck="true">// Fetch the nth word-sized system call argument as a string pointer.</span>
<span class="token comment" spellcheck="true">// Check that the pointer is valid and the string is nul-terminated.</span>
<span class="token comment" spellcheck="true">// (There is no shared writable memory, so the string can't change</span>
<span class="token comment" spellcheck="true">// between this check and being used by the kernel.)</span>
<span class="token keyword">int</span>
<span class="token function">argstr</span><span class="token punctuation">(</span><span class="token keyword">int</span> n<span class="token punctuation">,</span> <span class="token keyword">char</span> <span class="token operator">*</span><span class="token operator">*</span>pp<span class="token punctuation">)</span>
<span class="token punctuation">{</span>
  <span class="token keyword">int</span> addr<span class="token punctuation">;</span>
  <span class="token keyword">if</span><span class="token punctuation">(</span><span class="token function">argint</span><span class="token punctuation">(</span>n<span class="token punctuation">,</span> <span class="token operator">&amp;</span>addr<span class="token punctuation">)</span> <span class="token operator">&lt;</span> <span class="token number">0</span><span class="token punctuation">)</span>
    <span class="token keyword">return</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">;</span>
  <span class="token keyword">return</span> <span class="token function">fetchstr</span><span class="token punctuation">(</span>addr<span class="token punctuation">,</span> pp<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<h2 id="4-Add-trace-and-getcount"><a href="#4-Add-trace-and-getcount" class="headerlink" title="4. Add trace and getcount"></a>4. Add <code>trace</code> and <code>getcount</code></h2><p>After figuring out how the system call works in <code>xv6</code> system, we start to add <code>trace</code> and <code>getcount</code> systemcall.</p>
<h3 id="1-Add-system-call-number"><a href="#1-Add-system-call-number" class="headerlink" title="1. Add system call number"></a>1. Add system call number</h3><p>First, we need to add system call number in <code>syscall.h</code></p>
<pre class="line-numbers language-c"><code class="language-c"><span class="token comment" spellcheck="true">// my syscall</span>
<span class="token macro property">#<span class="token directive keyword">define</span> SYS_trace  22</span>
<span class="token macro property">#<span class="token directive keyword">define</span> SYS_getcount  23</span>
<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span></span></code></pre>
<p><img src="https://jack-1307599355.cos.ap-shanghai.myqcloud.com/%E6%88%AA%E5%B1%8F2022-09-26%20%E4%B8%8B%E5%8D%882.02.24.png" alt="Add Syscall number"></p>
<h3 id="2-Add-SYSCALL-Macro"><a href="#2-Add-SYSCALL-Macro" class="headerlink" title="2. Add SYSCALL Macro"></a>2. Add <code>SYSCALL</code> Macro</h3><p>The second step is to add <code>SYSCALL</code> macro in <code>usys.S</code></p>
<pre class="line-numbers language-assembly"><code class="language-assembly">SYSCALL(trace)
SYSCALL(getcount)
<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span></span></code></pre>
<p><img src="https://jack-1307599355.cos.ap-shanghai.myqcloud.com/%E6%88%AA%E5%B1%8F2022-09-26%20%E4%B8%8B%E5%8D%882.04.52.png" alt="Add SYSCALL Macro"></p>
<h3 id="3-Add-prototype-in-syscall-c"><a href="#3-Add-prototype-in-syscall-c" class="headerlink" title="3. Add prototype in syscall.c"></a>3. Add prototype in <code>syscall.c</code></h3><p>Add my system call function prototype in <code>syscall.c</code></p>
<pre class="line-numbers language-c"><code class="language-c"><span class="token comment" spellcheck="true">// my syscall</span>
<span class="token keyword">extern</span> <span class="token keyword">int</span> <span class="token function">sys_trace</span><span class="token punctuation">(</span><span class="token keyword">void</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">extern</span> <span class="token keyword">int</span> <span class="token function">sys_getcount</span><span class="token punctuation">(</span><span class="token keyword">void</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token keyword">static</span> <span class="token keyword">int</span> <span class="token punctuation">(</span><span class="token operator">*</span>syscalls<span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">(</span><span class="token keyword">void</span><span class="token punctuation">)</span> <span class="token operator">=</span> <span class="token punctuation">{</span>
<span class="token punctuation">[</span>SYS_fork<span class="token punctuation">]</span>    sys_fork<span class="token punctuation">,</span>
<span class="token punctuation">[</span>SYS_exit<span class="token punctuation">]</span>    sys_exit<span class="token punctuation">,</span>
<span class="token punctuation">[</span>SYS_wait<span class="token punctuation">]</span>    sys_wait<span class="token punctuation">,</span>
<span class="token punctuation">[</span>SYS_pipe<span class="token punctuation">]</span>    sys_pipe<span class="token punctuation">,</span>
<span class="token punctuation">[</span>SYS_read<span class="token punctuation">]</span>    sys_read<span class="token punctuation">,</span>
<span class="token punctuation">[</span>SYS_kill<span class="token punctuation">]</span>    sys_kill<span class="token punctuation">,</span>
<span class="token punctuation">[</span>SYS_exec<span class="token punctuation">]</span>    sys_exec<span class="token punctuation">,</span>
<span class="token punctuation">[</span>SYS_fstat<span class="token punctuation">]</span>   sys_fstat<span class="token punctuation">,</span>
<span class="token punctuation">[</span>SYS_chdir<span class="token punctuation">]</span>   sys_chdir<span class="token punctuation">,</span>
<span class="token punctuation">[</span>SYS_dup<span class="token punctuation">]</span>     sys_dup<span class="token punctuation">,</span>
<span class="token punctuation">[</span>SYS_getpid<span class="token punctuation">]</span>  sys_getpid<span class="token punctuation">,</span>
<span class="token punctuation">[</span>SYS_sbrk<span class="token punctuation">]</span>    sys_sbrk<span class="token punctuation">,</span>
<span class="token punctuation">[</span>SYS_sleep<span class="token punctuation">]</span>   sys_sleep<span class="token punctuation">,</span>
<span class="token punctuation">[</span>SYS_uptime<span class="token punctuation">]</span>  sys_uptime<span class="token punctuation">,</span>
<span class="token punctuation">[</span>SYS_open<span class="token punctuation">]</span>    sys_open<span class="token punctuation">,</span>
<span class="token punctuation">[</span>SYS_write<span class="token punctuation">]</span>   sys_write<span class="token punctuation">,</span>
<span class="token punctuation">[</span>SYS_mknod<span class="token punctuation">]</span>   sys_mknod<span class="token punctuation">,</span>
<span class="token punctuation">[</span>SYS_unlink<span class="token punctuation">]</span>  sys_unlink<span class="token punctuation">,</span>
<span class="token punctuation">[</span>SYS_link<span class="token punctuation">]</span>    sys_link<span class="token punctuation">,</span>
<span class="token punctuation">[</span>SYS_mkdir<span class="token punctuation">]</span>   sys_mkdir<span class="token punctuation">,</span>
<span class="token punctuation">[</span>SYS_close<span class="token punctuation">]</span>   sys_close<span class="token punctuation">,</span>
<span class="token punctuation">[</span>SYS_trace<span class="token punctuation">]</span> sys_trace<span class="token punctuation">,</span>
<span class="token punctuation">[</span>SYS_getcount<span class="token punctuation">]</span> sys_getcount
<span class="token punctuation">}</span><span class="token punctuation">;</span>
<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<h3 id="4-Realize-trace-and-getcount"><a href="#4-Realize-trace-and-getcount" class="headerlink" title="4. Realize trace and getcount"></a>4. Realize <code>trace</code> and <code>getcount</code></h3><p>Finally, realize <code>trace</code> and <code>getcount</code> in <code>sysfile.c</code></p>
<pre class="line-numbers language-c"><code class="language-c"><span class="token comment" spellcheck="true">// sysfile.c</span>

<span class="token comment" spellcheck="true">// my syscall data structure</span>
<span class="token keyword">typedef</span> <span class="token keyword">struct</span> trace_file
<span class="token punctuation">{</span>
  <span class="token keyword">char</span> filename<span class="token punctuation">[</span><span class="token number">256</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
  <span class="token keyword">int</span> open_counter<span class="token punctuation">;</span>
  <span class="token keyword">int</span> trace_enabled<span class="token punctuation">;</span>
<span class="token punctuation">}</span> trace_file<span class="token punctuation">;</span>

<span class="token keyword">int</span> num_traced<span class="token punctuation">;</span>
trace_file tracing_file<span class="token punctuation">;</span>

<span class="token keyword">int</span> <span class="token function">sys_trace</span><span class="token punctuation">(</span><span class="token keyword">void</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token comment" spellcheck="true">// get param from stack char *path;</span>
  <span class="token keyword">char</span> <span class="token operator">*</span>path<span class="token punctuation">;</span>
  <span class="token keyword">int</span> length <span class="token operator">=</span> <span class="token function">argstr</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">,</span> <span class="token operator">&amp;</span>path<span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token keyword">if</span> <span class="token punctuation">(</span>length <span class="token operator">&lt;</span> <span class="token number">0</span><span class="token punctuation">)</span>
    <span class="token keyword">return</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">;</span>

  <span class="token keyword">int</span> k <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>
  <span class="token keyword">for</span> <span class="token punctuation">(</span>k <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> k <span class="token operator">&lt;</span> length<span class="token punctuation">;</span> k<span class="token operator">++</span><span class="token punctuation">)</span>
    tracing_file<span class="token punctuation">.</span>filename<span class="token punctuation">[</span>k<span class="token punctuation">]</span> <span class="token operator">=</span> path<span class="token punctuation">[</span>k<span class="token punctuation">]</span><span class="token punctuation">;</span>
  tracing_file<span class="token punctuation">.</span>filename<span class="token punctuation">[</span>k<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token string">'\0'</span><span class="token punctuation">;</span>
tracing_file<span class="token punctuation">.</span>open_counter <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>
  tracing_file<span class="token punctuation">.</span>trace_enabled <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span>
  <span class="token keyword">return</span> <span class="token number">0</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>


<span class="token keyword">int</span> <span class="token function">sys_getcount</span><span class="token punctuation">(</span><span class="token keyword">void</span><span class="token punctuation">)</span><span class="token punctuation">{</span>
  <span class="token keyword">if</span> <span class="token punctuation">(</span>tracing_file<span class="token punctuation">.</span>trace_enabled <span class="token operator">==</span> <span class="token number">1</span><span class="token punctuation">)</span>
    <span class="token keyword">return</span> tracing_file<span class="token punctuation">.</span>open_counter<span class="token punctuation">;</span>
  <span class="token keyword">else</span>
    <span class="token keyword">return</span> <span class="token number">0</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<p>as well as modify <code>sysopen</code></p>
<pre class="line-numbers language-c"><code class="language-c"><span class="token keyword">int</span>
<span class="token function">sys_open</span><span class="token punctuation">(</span><span class="token keyword">void</span><span class="token punctuation">)</span>
<span class="token punctuation">{</span>
  <span class="token keyword">char</span> <span class="token operator">*</span>path<span class="token punctuation">;</span>
  <span class="token keyword">int</span> fd<span class="token punctuation">,</span> omode<span class="token punctuation">;</span>
  <span class="token keyword">struct</span> file <span class="token operator">*</span>f<span class="token punctuation">;</span>
  <span class="token keyword">struct</span> inode <span class="token operator">*</span>ip<span class="token punctuation">;</span>

  <span class="token comment" spellcheck="true">// check if trace enabled and add counter</span>
  <span class="token keyword">int</span> length <span class="token operator">=</span> <span class="token function">argstr</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">,</span> <span class="token operator">&amp;</span>path<span class="token punctuation">)</span><span class="token punctuation">;</span>

  <span class="token keyword">if</span><span class="token punctuation">(</span>length <span class="token operator">&lt;</span> <span class="token number">0</span> <span class="token operator">||</span> <span class="token function">argint</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token operator">&amp;</span>omode<span class="token punctuation">)</span> <span class="token operator">&lt;</span> <span class="token number">0</span><span class="token punctuation">)</span>
    <span class="token keyword">return</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">;</span>

  <span class="token keyword">char</span> <span class="token operator">*</span>ppath <span class="token operator">=</span> path<span class="token punctuation">;</span>
  <span class="token keyword">char</span> <span class="token operator">*</span>ptf <span class="token operator">=</span> tracing_file<span class="token punctuation">.</span>filename<span class="token punctuation">;</span>
  <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">strncmp</span><span class="token punctuation">(</span>ppath<span class="token punctuation">,</span> ptf<span class="token punctuation">,</span> length<span class="token punctuation">)</span> <span class="token operator">==</span> <span class="token number">0</span><span class="token punctuation">)</span>
    <span class="token keyword">if</span> <span class="token punctuation">(</span>tracing_file<span class="token punctuation">.</span>trace_enabled<span class="token punctuation">)</span>
      tracing_file<span class="token punctuation">.</span>open_counter <span class="token operator">+</span><span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span>


  <span class="token function">begin_op</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

  <span class="token keyword">if</span><span class="token punctuation">(</span>omode <span class="token operator">&amp;</span> O_CREATE<span class="token punctuation">)</span><span class="token punctuation">{</span>
    ip <span class="token operator">=</span> <span class="token function">create</span><span class="token punctuation">(</span>path<span class="token punctuation">,</span> T_FILE<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">if</span><span class="token punctuation">(</span>ip <span class="token operator">==</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">{</span>
      <span class="token function">end_op</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
      <span class="token keyword">return</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
  <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span>
    <span class="token keyword">if</span><span class="token punctuation">(</span><span class="token punctuation">(</span>ip <span class="token operator">=</span> <span class="token function">namei</span><span class="token punctuation">(</span>path<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token operator">==</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">{</span>
      <span class="token function">end_op</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
      <span class="token keyword">return</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
    <span class="token function">ilock</span><span class="token punctuation">(</span>ip<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">if</span><span class="token punctuation">(</span>ip<span class="token operator">-></span>type <span class="token operator">==</span> T_DIR <span class="token operator">&amp;&amp;</span> omode <span class="token operator">!=</span> O_RDONLY<span class="token punctuation">)</span><span class="token punctuation">{</span>
      <span class="token function">iunlockput</span><span class="token punctuation">(</span>ip<span class="token punctuation">)</span><span class="token punctuation">;</span>
      <span class="token function">end_op</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
      <span class="token keyword">return</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
  <span class="token punctuation">}</span>

  <span class="token keyword">if</span><span class="token punctuation">(</span><span class="token punctuation">(</span>f <span class="token operator">=</span> <span class="token function">filealloc</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token operator">==</span> <span class="token number">0</span> <span class="token operator">||</span> <span class="token punctuation">(</span>fd <span class="token operator">=</span> <span class="token function">fdalloc</span><span class="token punctuation">(</span>f<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token operator">&lt;</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">{</span>
    <span class="token keyword">if</span><span class="token punctuation">(</span>f<span class="token punctuation">)</span>
      <span class="token function">fileclose</span><span class="token punctuation">(</span>f<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token function">iunlockput</span><span class="token punctuation">(</span>ip<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token function">end_op</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">return</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">;</span>
  <span class="token punctuation">}</span>
  <span class="token function">iunlock</span><span class="token punctuation">(</span>ip<span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token function">end_op</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

  f<span class="token operator">-></span>type <span class="token operator">=</span> FD_INODE<span class="token punctuation">;</span>
  f<span class="token operator">-></span>ip <span class="token operator">=</span> ip<span class="token punctuation">;</span>
  f<span class="token operator">-></span>off <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>
  f<span class="token operator">-></span>readable <span class="token operator">=</span> <span class="token operator">!</span><span class="token punctuation">(</span>omode <span class="token operator">&amp;</span> O_WRONLY<span class="token punctuation">)</span><span class="token punctuation">;</span>
  f<span class="token operator">-></span>writable <span class="token operator">=</span> <span class="token punctuation">(</span>omode <span class="token operator">&amp;</span> O_WRONLY<span class="token punctuation">)</span> <span class="token operator">||</span> <span class="token punctuation">(</span>omode <span class="token operator">&amp;</span> O_RDWR<span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token keyword">return</span> fd<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<p><img src="https://jack-1307599355.cos.ap-shanghai.myqcloud.com/%E6%88%AA%E5%B1%8F2022-09-26%20%E4%B8%8B%E5%8D%882.12.01.png" alt="Add sys_trace and sys_getcount"></p>
<p><img src="https://jack-1307599355.cos.ap-shanghai.myqcloud.com/%E6%88%AA%E5%B1%8F2022-09-26%20%E4%B8%8B%E5%8D%882.11.49.png" alt="Modify sys_open"></p>
<h2 id="5-Result"><a href="#5-Result" class="headerlink" title="5. Result"></a>5. Result</h2><p>Since this blog is actually a project of CS537: Operating System of UW-Madison, so the course do offer a test script to test the system call you developed.</p>
<p>PS: The courses material is open source, and serves as material of the book Operating System: Three Easy Piece by Remzi, the lecture of this course. He create a repository called OS Steps, and pull all course materials like project introduction, project testing tools in that material. So maybe you can find the testing script in Remzi’s github.</p>
<p>To strat test, simply</p>
<pre class="line-numbers language-bash"><code class="language-bash">~cs537-1/test/p1b/runtest.sh -c
<span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre>
<p><img src="https://jack-1307599355.cos.ap-shanghai.myqcloud.com/%E6%88%AA%E5%B1%8F2022-09-26%20%E4%B8%8B%E5%8D%882.14.21.png" alt="Test Result"></p>

                
            </div>
            <hr/>

            

    <div class="reprint" id="reprint-statement">
        
            <div class="reprint__author">
                <span class="reprint-meta" style="font-weight: bold;">
                    <i class="fas fa-user">
                        文章作者:
                    </i>
                </span>
                <span class="reprint-info">
                    <a href="/about" rel="external nofollow noreferrer">Jack Wang</a>
                </span>
            </div>
            <div class="reprint__type">
                <span class="reprint-meta" style="font-weight: bold;">
                    <i class="fas fa-link">
                        文章链接:
                    </i>
                </span>
                <span class="reprint-info">
                    <a href="https://jackwang0107.github.io/2022/09/27/add-system-call-for-xv6/">https://jackwang0107.github.io/2022/09/27/add-system-call-for-xv6/</a>
                </span>
            </div>
            <div class="reprint__notice">
                <span class="reprint-meta" style="font-weight: bold;">
                    <i class="fas fa-copyright">
                        版权声明:
                    </i>
                </span>
                <span class="reprint-info">
                    本博客所有文章除特別声明外，均采用
                    <a href="https://creativecommons.org/licenses/by/4.0/deed.zh" rel="external nofollow noreferrer" target="_blank">CC BY 4.0</a>
                    许可协议。转载请注明来源
                    <a href="/about" target="_blank">Jack Wang</a>
                    !
                </span>
            </div>
        
    </div>

    <script async defer>
      document.addEventListener("copy", function (e) {
        let toastHTML = '<span>复制成功，请遵循本文的转载规则</span><button class="btn-flat toast-action" onclick="navToReprintStatement()" style="font-size: smaller">查看</a>';
        M.toast({html: toastHTML})
      });

      function navToReprintStatement() {
        $("html, body").animate({scrollTop: $("#reprint-statement").offset().top - 80}, 800);
      }
    </script>



            <div class="tag_share" style="display: block;">
                <div class="post-meta__tag-list" style="display: inline-block;">
                    
                        <div class="article-tag">
                            
                                <a href="/tags/Operating-System/">
                                    <span class="chip bg-color">Operating System</span>
                                </a>
                            
                                <a href="/tags/xv6/">
                                    <span class="chip bg-color">xv6</span>
                                </a>
                            
                        </div>
                    
                </div>
                <div class="post_share" style="zoom: 80%; width: fit-content; display: inline-block; float: right; margin: -0.15rem 0;">
                    <link rel="stylesheet" type="text/css" href="/libs/share/css/share.min.css">
<div id="article-share">

    
    <div class="social-share" data-sites="twitter,facebook,google,qq,qzone,wechat,weibo,douban,linkedin" data-wechat-qrcode-helper="<p>微信扫一扫即可分享！</p>"></div>
    <script src="/libs/share/js/social-share.min.js"></script>
    

    

</div>

                </div>
            </div>
            
                <style>
    #reward {
        margin: 40px 0;
        text-align: center;
    }

    #reward .reward-link {
        font-size: 1.4rem;
        line-height: 38px;
    }

    #reward .btn-floating:hover {
        box-shadow: 0 6px 12px rgba(0, 0, 0, 0.2), 0 5px 15px rgba(0, 0, 0, 0.2);
    }

    #rewardModal {
        width: 320px;
        height: 350px;
    }

    #rewardModal .reward-title {
        margin: 15px auto;
        padding-bottom: 5px;
    }

    #rewardModal .modal-content {
        padding: 10px;
    }

    #rewardModal .close {
        position: absolute;
        right: 15px;
        top: 15px;
        color: rgba(0, 0, 0, 0.5);
        font-size: 1.3rem;
        line-height: 20px;
        cursor: pointer;
    }

    #rewardModal .close:hover {
        color: #ef5350;
        transform: scale(1.3);
        -moz-transform:scale(1.3);
        -webkit-transform:scale(1.3);
        -o-transform:scale(1.3);
    }

    #rewardModal .reward-tabs {
        margin: 0 auto;
        width: 210px;
    }

    .reward-tabs .tabs {
        height: 38px;
        margin: 10px auto;
        padding-left: 0;
    }

    .reward-content ul {
        padding-left: 0 !important;
    }

    .reward-tabs .tabs .tab {
        height: 38px;
        line-height: 38px;
    }

    .reward-tabs .tab a {
        color: #fff;
        background-color: #ccc;
    }

    .reward-tabs .tab a:hover {
        background-color: #ccc;
        color: #fff;
    }

    .reward-tabs .wechat-tab .active {
        color: #fff !important;
        background-color: #22AB38 !important;
    }

    .reward-tabs .alipay-tab .active {
        color: #fff !important;
        background-color: #019FE8 !important;
    }

    .reward-tabs .reward-img {
        width: 210px;
        height: 210px;
    }
</style>

<div id="reward">
    <a href="#rewardModal" class="reward-link modal-trigger btn-floating btn-medium waves-effect waves-light red">赏</a>

    <!-- Modal Structure -->
    <div id="rewardModal" class="modal">
        <div class="modal-content">
            <a class="close modal-close"><i class="fas fa-times"></i></a>
            <h4 class="reward-title">你的赏识是我前进的动力</h4>
            <div class="reward-content">
                <div class="reward-tabs">
                    <ul class="tabs row">
                        <li class="tab col s6 alipay-tab waves-effect waves-light"><a href="#alipay">支付宝</a></li>
                        <li class="tab col s6 wechat-tab waves-effect waves-light"><a href="#wechat">微 信</a></li>
                    </ul>
                    <div id="alipay">
                        <img src="/medias/reward/alipay.png" class="reward-img" alt="支付宝打赏二维码">
                    </div>
                    <div id="wechat">
                        <img src="/medias/reward/wechat.jpg" class="reward-img" alt="微信打赏二维码">
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>

<script>
    $(function () {
        $('.tabs').tabs();
    });
</script>

            
        </div>
    </div>

    

    

    

    

    

    

    

    

    

<article id="prenext-posts" class="prev-next articles">
    <div class="row article-row">
        
        <div class="article col s12 m6" data-aos="fade-up">
            <div class="article-badge left-badge text-color">
                <i class="fas fa-chevron-left"></i>&nbsp;上一篇</div>
            <div class="card">
                <a href="/2022/09/29/hexo-matery-zhu-ti-dai-ma-gao-liang-shi-xiao/">
                    <div class="card-image">
                        
                        <img src="https://jack-1307599355.cos.ap-shanghai.myqcloud.com/image-20220929014633108.png" class="responsive-img" alt="hexo matery主题代码高亮失效">
                        
                        <span class="card-title">hexo matery主题代码高亮失效</span>
                    </div>
                </a>
                <div class="card-content article-content">
                    <div class="summary block-with-text">
                        
                            本文主要介绍了hexo matery主题代码高亮失效的解决办法
                        
                    </div>
                    <div class="publish-info">
                        <span class="publish-date">
                            <i class="far fa-clock fa-fw icon-date"></i>2022-09-29
                        </span>
                        <span class="publish-author">
                            
                            <i class="fas fa-bookmark fa-fw icon-category"></i>
                            
                            <a href="/categories/%E6%9D%82%E9%A1%B9/" class="post-category">
                                    杂项
                                </a>
                            
                            
                        </span>
                    </div>
                </div>
                
                <div class="card-action article-tags">
                    
                    <a href="/tags/Hexo/">
                        <span class="chip bg-color">Hexo</span>
                    </a>
                    
                </div>
                
            </div>
        </div>
        
        
        <div class="article col s12 m6" data-aos="fade-up">
            <div class="article-badge right-badge text-color">
                下一篇&nbsp;<i class="fas fa-chevron-right"></i>
            </div>
            <div class="card">
                <a href="/2022/07/29/ubuntu-di-pin-shi-yong-ming-ling/">
                    <div class="card-image">
                        
                        <img src="https://jack-1307599355.cos.ap-shanghai.myqcloud.com/image-20220729210010695.png" class="responsive-img" alt="Ubuntu低频实用命令">
                        
                        <span class="card-title">Ubuntu低频实用命令</span>
                    </div>
                </a>
                <div class="card-content article-content">
                    <div class="summary block-with-text">
                        
                            本文主要介绍了Linux(Ubuntu)系统下低频但是却非常实用的命令
                        
                    </div>
                    <div class="publish-info">
                            <span class="publish-date">
                                <i class="far fa-clock fa-fw icon-date"></i>2022-07-29
                            </span>
                        <span class="publish-author">
                            
                            <i class="fas fa-bookmark fa-fw icon-category"></i>
                            
                            <a href="/categories/Linux%E5%AE%9E%E7%94%A8%E6%8A%80%E5%B7%A7/" class="post-category">
                                    Linux实用技巧
                                </a>
                            
                            
                        </span>
                    </div>
                </div>
                
                <div class="card-action article-tags">
                    
                    <a href="/tags/Linux/">
                        <span class="chip bg-color">Linux</span>
                    </a>
                    
                    <a href="/tags/Ubuntu/">
                        <span class="chip bg-color">Ubuntu</span>
                    </a>
                    
                </div>
                
            </div>
        </div>
        
    </div>
</article>

</div>


<script>
    $('#articleContent').on('copy', function (e) {
        // IE8 or earlier browser is 'undefined'
        if (typeof window.getSelection === 'undefined') return;

        var selection = window.getSelection();
        // if the selection is short let's not annoy our users.
        if (('' + selection).length < Number.parseInt('120')) {
            return;
        }

        // create a div outside of the visible area and fill it with the selected text.
        var bodyElement = document.getElementsByTagName('body')[0];
        var newdiv = document.createElement('div');
        newdiv.style.position = 'absolute';
        newdiv.style.left = '-99999px';
        bodyElement.appendChild(newdiv);
        newdiv.appendChild(selection.getRangeAt(0).cloneContents());

        // we need a <pre> tag workaround.
        // otherwise the text inside "pre" loses all the line breaks!
        if (selection.getRangeAt(0).commonAncestorContainer.nodeName === 'PRE' || selection.getRangeAt(0).commonAncestorContainer.nodeName === 'CODE') {
            newdiv.innerHTML = "<pre>" + newdiv.innerHTML + "</pre>";
        }

        var url = document.location.href;
        newdiv.innerHTML += '<br />'
            + '来源: JackWang&#39;s Blog<br />'
            + '文章作者: Jack Wang<br />'
            + '文章链接: <a href="' + url + '">' + url + '</a><br />'
            + '本文章著作权归作者所有，任何形式的转载都请注明出处。';

        selection.selectAllChildren(newdiv);
        window.setTimeout(function () {bodyElement.removeChild(newdiv);}, 200);
    });
</script>


<!-- 代码块功能依赖 -->
<script type="text/javascript" src="/libs/codeBlock/codeBlockFuction.js"></script>

<!-- 代码语言 -->

<script type="text/javascript" src="/libs/codeBlock/codeLang.js"></script>


<!-- 代码块复制 -->

<script type="text/javascript" src="/libs/codeBlock/codeCopy.js"></script>


<!-- 代码块收缩 -->

<script type="text/javascript" src="/libs/codeBlock/codeShrink.js"></script>


    </div>
    <div id="toc-aside" class="expanded col l3 hide-on-med-and-down">
        <div class="toc-widget card" style="background-color: white;">
            <div class="toc-title"><i class="far fa-list-alt"></i>&nbsp;&nbsp;目录</div>
            <div id="toc-content"></div>
        </div>
    </div>
</div>

<!-- TOC 悬浮按钮. -->

<div id="floating-toc-btn" class="hide-on-med-and-down">
    <a class="btn-floating btn-large bg-color">
        <i class="fas fa-list-ul"></i>
    </a>
</div>


<script src="/libs/tocbot/tocbot.min.js"></script>
<script>
    $(function () {
        tocbot.init({
            tocSelector: '#toc-content',
            contentSelector: '#articleContent',
            headingsOffset: -($(window).height() * 0.4 - 45),
            collapseDepth: Number('2'),
            headingSelector: 'h1, h2, h3, h4, h5, h6'
        });

        // modify the toc link href to support Chinese.
        let i = 0;
        let tocHeading = 'toc-heading-';
        $('#toc-content a').each(function () {
            $(this).attr('href', '#' + tocHeading + (++i));
        });

        // modify the heading title id to support Chinese.
        i = 0;
        $('#articleContent').children('h1, h2, h3, h4, h5, h6').each(function () {
            $(this).attr('id', tocHeading + (++i));
        });

        // Set scroll toc fixed.
        let tocHeight = parseInt($(window).height() * 0.4 - 64);
        let $tocWidget = $('.toc-widget');
        $(window).scroll(function () {
            let scroll = $(window).scrollTop();
            /* add post toc fixed. */
            if (scroll > tocHeight) {
                $tocWidget.addClass('toc-fixed');
            } else {
                $tocWidget.removeClass('toc-fixed');
            }
        });

        
        /* 修复文章卡片 div 的宽度. */
        let fixPostCardWidth = function (srcId, targetId) {
            let srcDiv = $('#' + srcId);
            if (srcDiv.length === 0) {
                return;
            }

            let w = srcDiv.width();
            if (w >= 450) {
                w = w + 21;
            } else if (w >= 350 && w < 450) {
                w = w + 18;
            } else if (w >= 300 && w < 350) {
                w = w + 16;
            } else {
                w = w + 14;
            }
            $('#' + targetId).width(w);
        };

        // 切换TOC目录展开收缩的相关操作.
        const expandedClass = 'expanded';
        let $tocAside = $('#toc-aside');
        let $mainContent = $('#main-content');
        $('#floating-toc-btn .btn-floating').click(function () {
            if ($tocAside.hasClass(expandedClass)) {
                $tocAside.removeClass(expandedClass).hide();
                $mainContent.removeClass('l9');
            } else {
                $tocAside.addClass(expandedClass).show();
                $mainContent.addClass('l9');
            }
            fixPostCardWidth('artDetail', 'prenext-posts');
        });
        
    });
</script>

    

</main>




    <footer class="page-footer bg-color">
    

    <div class="container row center-align"
         style="margin-bottom: 15px !important;">
        <div class="col s12 m8 l8 copy-right">
            Copyright&nbsp;&copy;
            
                <span id="year">2021-2023</span>
            
            <a href="/about" target="_blank">Jack Wang</a>
            <!-- |&nbsp;Powered by&nbsp;<a href="https://hexo.io/" target="_blank">Hexo</a> -->
            <!-- |&nbsp;Theme&nbsp;<a href="https://github.com/blinkfox/hexo-theme-matery" target="_blank">Matery</a> -->
            <br>
            
                &nbsp;<i class="fas fa-chart-area"></i>&nbsp;站点总字数:&nbsp;<span
                        class="white-color">603.8k</span>
            
            
            
                
            
            
                <span id="busuanzi_container_site_pv">
                &nbsp;|&nbsp;<i class="far fa-eye"></i>&nbsp;总访问量:&nbsp;
                    <span id="busuanzi_value_site_pv" class="white-color"></span>
            </span>
            
            
                <span id="busuanzi_container_site_uv">
                &nbsp;|&nbsp;<i class="fas fa-users"></i>&nbsp;总访问人数:&nbsp;
                    <span id="busuanzi_value_site_uv" class="white-color"></span>
            </span>
            
            <br>

            <!-- 运行天数提醒. -->
            
                <span id="sitetime"> Loading ...</span>
                <script>
                    var calcSiteTime = function () {
                        var seconds = 1000;
                        var minutes = seconds * 60;
                        var hours = minutes * 60;
                        var days = hours * 24;
                        var years = days * 365;
                        var today = new Date();
                        var startYear = "2021";
                        var startMonth = "11";
                        var startDate = "12";
                        var startHour = "0";
                        var startMinute = "0";
                        var startSecond = "0";
                        var todayYear = today.getFullYear();
                        var todayMonth = today.getMonth() + 1;
                        var todayDate = today.getDate();
                        var todayHour = today.getHours();
                        var todayMinute = today.getMinutes();
                        var todaySecond = today.getSeconds();
                        var t1 = Date.UTC(startYear, startMonth, startDate, startHour, startMinute, startSecond);
                        var t2 = Date.UTC(todayYear, todayMonth, todayDate, todayHour, todayMinute, todaySecond);
                        var diff = t2 - t1;
                        var diffYears = Math.floor(diff / years);
                        var diffDays = Math.floor((diff / days) - diffYears * 365);

                        // 区分是否有年份.
                        var language = 'zh-CN';
                        if (startYear === String(todayYear)) {
                            document.getElementById("year").innerHTML = todayYear;
                            var daysTip = 'This site has been running for ' + diffDays + ' days';
                            if (language === 'zh-CN') {
                                daysTip = '本站已运行 ' + diffDays + ' 天';
                            } else if (language === 'zh-HK') {
                                daysTip = '本站已運行 ' + diffDays + ' 天';
                            }
                            document.getElementById("sitetime").innerHTML = daysTip;
                        } else {
                            document.getElementById("year").innerHTML = startYear + " - " + todayYear;
                            var yearsAndDaysTip = 'This site has been running for ' + diffYears + ' years and '
                                + diffDays + ' days';
                            if (language === 'zh-CN') {
                                yearsAndDaysTip = '本站已运行 ' + diffYears + ' 年 ' + diffDays + ' 天';
                            } else if (language === 'zh-HK') {
                                yearsAndDaysTip = '本站已運行 ' + diffYears + ' 年 ' + diffDays + ' 天';
                            }
                            document.getElementById("sitetime").innerHTML = yearsAndDaysTip;
                        }
                    }

                    calcSiteTime();
                </script>
            
            <br>
            
                <span id="icp"><img src="/medias/icp.png"
                                    style="vertical-align: text-bottom;"/>
                <a href="https://beian.miit.gov.cn" target="_blank">陕ICP备2021014294号-1</a>
            </span>
            
        </div>
        <div class="col s12 m4 l4 social-link social-statis">
    <a href="https://github.com/jackwang0108" class="tooltipped" target="_blank" data-tooltip="访问我的GitHub" data-position="top" data-delay="50">
        <i class="fab fa-github"></i>
    </a>



    <a href="mailto:2232123545@qq.com" class="tooltipped" target="_blank" data-tooltip="邮件联系我" data-position="top" data-delay="50">
        <i class="fas fa-envelope-open"></i>
    </a>







    <a href="tencent://AddContact/?fromId=50&fromSubId=1&subcmd=all&uin=2232123545" class="tooltipped" target="_blank" data-tooltip="QQ联系我: 2232123545" data-position="top" data-delay="50">
        <i class="fab fa-qq"></i>
    </a>







</div>
    </div>
</footer>

<div class="progress-bar"></div>


    <!-- 搜索遮罩框 -->
<div id="searchModal" class="modal">
    <div class="modal-content">
        <div class="search-header">
            <span class="title"><i class="fas fa-search"></i>&nbsp;&nbsp;搜索</span>
            <input type="search" id="searchInput" name="s" placeholder="请输入搜索的关键字"
                   class="search-input">
        </div>
        <div id="searchResult"></div>
    </div>
</div>

<script type="text/javascript">
$(function () {
    var searchFunc = function (path, search_id, content_id) {
        'use strict';
        $.ajax({
            url: path,
            dataType: "xml",
            success: function (xmlResponse) {
                // get the contents from search data
                var datas = $("entry", xmlResponse).map(function () {
                    return {
                        title: $("title", this).text(),
                        content: $("content", this).text(),
                        url: $("url", this).text()
                    };
                }).get();
                var $input = document.getElementById(search_id);
                var $resultContent = document.getElementById(content_id);
                $input.addEventListener('input', function () {
                    var str = '<ul class=\"search-result-list\">';
                    var keywords = this.value.trim().toLowerCase().split(/[\s\-]+/);
                    $resultContent.innerHTML = "";
                    if (this.value.trim().length <= 0) {
                        return;
                    }
                    // perform local searching
                    datas.forEach(function (data) {
                        var isMatch = true;
                        var data_title = data.title.trim().toLowerCase();
                        var data_content = data.content.trim().replace(/<[^>]+>/g, "").toLowerCase();
                        var data_url = data.url;
                        data_url = data_url.indexOf('/') === 0 ? data.url : '/' + data_url;
                        var index_title = -1;
                        var index_content = -1;
                        var first_occur = -1;
                        // only match artiles with not empty titles and contents
                        if (data_title !== '' && data_content !== '') {
                            keywords.forEach(function (keyword, i) {
                                index_title = data_title.indexOf(keyword);
                                index_content = data_content.indexOf(keyword);
                                if (index_title < 0 && index_content < 0) {
                                    isMatch = false;
                                } else {
                                    if (index_content < 0) {
                                        index_content = 0;
                                    }
                                    if (i === 0) {
                                        first_occur = index_content;
                                    }
                                }
                            });
                        }
                        // show search results
                        if (isMatch) {
                            str += "<li><a href='" + data_url + "' class='search-result-title'>" + data_title + "</a>";
                            var content = data.content.trim().replace(/<[^>]+>/g, "");
                            if (first_occur >= 0) {
                                // cut out 100 characters
                                var start = first_occur - 20;
                                var end = first_occur + 80;
                                if (start < 0) {
                                    start = 0;
                                }
                                if (start === 0) {
                                    end = 100;
                                }
                                if (end > content.length) {
                                    end = content.length;
                                }
                                var match_content = content.substr(start, end);
                                // highlight all keywords
                                keywords.forEach(function (keyword) {
                                    var regS = new RegExp(keyword, "gi");
                                    match_content = match_content.replace(regS, "<em class=\"search-keyword\">" + keyword + "</em>");
                                });

                                str += "<p class=\"search-result\">" + match_content + "...</p>"
                            }
                            str += "</li>";
                        }
                    });
                    str += "</ul>";
                    $resultContent.innerHTML = str;
                });
            }
        });
    };

    searchFunc('/search.xml', 'searchInput', 'searchResult');
});
</script>

    <!-- 回到顶部按钮 -->
<div id="backTop" class="top-scroll">
    <a class="btn-floating btn-large waves-effect waves-light" href="#!">
        <i class="fas fa-arrow-up"></i>
    </a>
</div>


    <script src="/libs/materialize/materialize.min.js"></script>
    <script src="/libs/masonry/masonry.pkgd.min.js"></script>
    <script src="/libs/aos/aos.js"></script>
    <script src="/libs/scrollprogress/scrollProgress.min.js"></script>
    <script src="/libs/lightGallery/js/lightgallery-all.min.js"></script>
    <script src="/js/matery.js"></script>

    

    
        
        <script type="text/javascript">
            // 只在桌面版网页启用特效
            var windowWidth = $(window).width();
            if (windowWidth > 768) {
                document.write('<script type="text/javascript" src="/libs/others/sakura.js"><\/script>');
            }
        </script>
    

    <!-- 雪花特效 -->
    

    <!-- 鼠标星星特效 -->
    

     
        <script src="https://ssl.captcha.qq.com/TCaptcha.js"></script>
        <script src="/libs/others/TencentCaptcha.js"></script>
        <button id="TencentCaptcha" data-appid="xxxxxxxxxx" data-cbfn="callback" type="button" hidden></button>
    

    <!-- Baidu Analytics -->

    <!-- Baidu Push -->

<script>
    (function () {
        var bp = document.createElement('script');
        var curProtocol = window.location.protocol.split(':')[0];
        if (curProtocol === 'https') {
            bp.src = 'https://zz.bdstatic.com/linksubmit/push.js';
        } else {
            bp.src = 'http://push.zhanzhang.baidu.com/push.js';
        }
        var s = document.getElementsByTagName("script")[0];
        s.parentNode.insertBefore(bp, s);
    })();
</script>

    
    <script src="/libs/others/clicklove.js" async="async"></script>
    
    
    <script async src="/libs/others/busuanzi.pure.mini.js"></script>
    

    

    

    <!--腾讯兔小巢-->
    
    

    

    

    
    <script src="/libs/instantpage/instantpage.js" type="module"></script>
    

</body>

</html>
